La clase Vector

Anuncio
Calculando notas en C++
• Se desea escribir un programa en C++ que
calcule la nota final de una asignatura
• Esta nota final se calcula como
Vectores en C++
0.2*Examen1 + 0.4*Examen2 + 0.4*prom. Tareas
• Queremos conocer la nota final con 3
décimas de precisión
Programación Orientada a Objeto
Ing. Civil en Telecomunicaciones
Calculando notas en C++
Calculando notas en C++
#include <iostream>
#include <string>
// Solicita las notas de las tareas
cout << "Ingrese las notas de sus tareas, terminando con Ctrl-D: ";
// Indica que el programa usara estos objetos
// Esto puede ser reemplazado por using namespace std;
using std::cin;
using std::cout;
using std::endl;
using std::string;
// Contador y sumatoria de las notas
int contador = 0;
double suma = 0;
int main()
{
// Solicita el nombre del alumno
cout << "Ingrese su nombre: ";
string nombre;
cin >> nombre;
cout << "Hola, " << nombre << "!" << endl;
// Ciclo de lectura
while (cin >> temp) {
++contador;
suma += temp;
}
// Solicita las notas de los examenes
cout << "Ingrese las notas de sus examenes: ";
double examen1, examen2;
cin >> examen1 >> examen2;
Comando using
• En el programa usamos varias veces los
objetos std::cin, std::cout,
std::endl, std::string
std::cin indica al
compilador que toda referencia a cin es a
std::cin
Permite abreviar el nombre del objeto
// Variable auxiliar
double temp;
// Escribe el resultado
cout << "Su nota final es " << 0.2*examen1 + 0.4*examen2 +
0.4*suma/contador << endl;
return 0;
}
Entrada de datos encadenada y fin
de archivo
•
Declaración using
• Podemos ahorrar trabajo usando el
comando using namespace std;
Al igual que se encadenan salidas de
datos a cout, se pueden encadenar
entradas de datos desde std::cin
cin >> examen1 >> examen2
El programa espera que se ingresen 2 datos
antes de continuar
•
Entrada de datos termina ante fin de
archivo
© 2015 Mario Medina C.
O su equivalente ASCII, Control-D
1
Precisión de resultados
Precisión de resultados
• Ejemplo anterior no fija la precisión del
resultado
#include <iomanip>
Es necesario usar los manipuladores
de flujo
setprecision() y fixed()
Necesario incluir <iomanip>
• Además, vamos a usar la función miembro
cout.precision() para obtener la
precisión actual para luego restaurarla
// Escribe el resultado
streamsize prec = cout.precision();
cout << "Su nota final es " << fixed << setprecision(3) <<
0.2*examen1 + 0.4*examen2 + 0.4*suma/contador
<< setprecision(prec) << endl;
fixed y setprecision(3) imprime 3
dígitos significativos
Precisión actual se almacena en objeto de
tipo streamsize
Calculando notas en C++
Calculando la mediana
• Ahora, en vez de usar el promedio de las
tareas, se quiere usar la mediana de las
notas
• Qué es la mediana?
• Suponiendo que la lista Q tiene N notas
ordenadas
• N impar: mediana es el elemento Q(N – 1)/2
“El elemento del medio” de una lista
El valor de una lista que deja el mismo
número de datos antes y después que él
Aquel valor que divide al conjunto en dos
partes iguales
Mediana de 3.4, 4.5, 5.6, 6.1, 6.9 es 5.6
• N par: mediana es el promedio de los
elementos QN/2 y Q(N – 1)/2
Mediana de 3.4, 4.5, 5.6, 5.8, 6.1, 6.9 es 5.7
Calculando la mediana
Lectura de datos a un vector
• Para calcular la mediana de una lista de
notas, todas las notas deben estar a mano
• Almacenar los datos en un vector
• Declaración de vector de tipo double
• Función miembro push_back() agrega
elemento al final del vector
Clase de C++ que almacena
una secuencia de
datos del mismo tipo
Acceso via subíndices en forma similar a C
Varía su tamaño en forma dinámica sin necesidad
de solicitar memoria al S. O.
Funciones miembros para tareas comunes
© 2015 Mario Medina C.
// Vector de notas
vector<double> notas;
double temp;
while (cin >> temp) {
notas.push_back(temp);
}
2
Cálculo de la mediana
• Cálculo de la mediana usando el operador
?: del C
Variable mid contiene tamaño del vector/2
double mediana;
mediana = (size%2 == 0) ? (notas[mid] +
notas[mid - 1])/2 : notas[mid];
Cálculo de la mediana
• Almacenar tamaño del vector en una variable
typedef vector<double>::size_type vec_size;
vec_size size = notas.size();
if (size == 0) {
cout << endl << "Debe ingresar al menos
una nota. Intente de nuevo " << endl;
return 1;
Qué pasa si vector está vacío?
notas[mid – 1] falla
Vector no valida rango de acceso
}
Comando typedef
Cálculo de la mediana
• Tamano de un vector de double es un
entero de tipo vector<double>::size_type
• Comando typedef permite definir nuevo
nombre para ese tipo de dato
• Cálculo de la mediana requiere que los
datos estén ordenados en forma nodecreciente
typedef vector<double>::size_type vec_size;
De esta forma, se escribe menos y se evitan
errores
La interpretacion de typedef es hecha por
el compilador
Calculando la mediana en C++ (I)
#include
#include
#include
#include
#include
<algorithm>
<iomanip>
<iostream>
<string>
<vector>
// Indica que programa usara objetos de biblioteca estandar
using namespace std;
int main()
{
// Solicita el nombre del alumno
cout << "Ingrese su nombre: ";
string nombre;
cin >> nombre;
cout << "Hola, " << nombre << "!" << endl;
© 2015 Mario Medina C.
Para eso, usaremos función sort() de la
biblioteca de algoritmos de C++
sort(notas.begin(), notas.end());
Declarada en <algorithm>
Sus argumentos son iteradores al primer y
último elemento del vector a ordenar
Calculando la mediana en C++ (II)
// Solicita las notas de los examenes
cout << "Ingrese las notas de sus examenes: ";
double examen1, examen2;
cin >> examen1 >> examen2;
// Solicita las notas de las tareas
cout << "Ingrese sus tareas, terminando con ^D: ";
vector<double> notas;
double temp;
// Vector de notas
// Variable auxiliar
// Ciclo de lectura
while (cin >> temp) {
notas.push_back(temp);
}
3
Calculando la mediana en C++ (III)
// Verificar que se ingresaron notas
typedef vector<double>::size_type vec_size;
vec_size size = notas.size();
if (size == 0) {
cout << endl << "Debe ingresar al menos una nota. “
<< "Intente de nuevo " << endl;
return 1;
}
// Ordenar las notas
sort(notas.begin(), notas.end());
Calculando la mediana en C++ (IV)
// Escribe el resultado
// Almacena la precision actual para no perderla
streamsize prec = cout.precision();
cout << "Su nota final es " << fixed
<< setprecision(3) <<
0.2*examen1 + 0.4*examen2 + 0.4*mediana
<< setprecision(prec) << endl;
return 0;
}
// Calcular la mediana
vec_size mid = size/2;
double mediana;
mediana = (size%2 == 0) ? (notas[mid] + notas[mid - 1])/2
: notas[mid];
Más sobre vector()
Inicializacion mediante listas
• En vez de usar if (size == 0) {, podría
haberse usado la función miembro
datos.empty(), que retorna un valor
booleano true si el vector está vacío
• El estándar garantiza que los elementos de un
vector están almacenados en forma contigua en
memoria
• Función miembro data() retorna un puntero
al primer elemento del vector (C++11)
• En C++, es posible inicializar variables
mediante asignacion o mediante listas
Inicializacion de vectores via listas
Inicializadores de objetos via listas
• C++03 tenia inconsistencias en la
inicialización de vectores mediante listas
• En C++11, las siguientes inicializaciones
son válidas
int vect[5] = {0, 1, 2, 3, 4}; // valido
vector<int> vec[5] = {0, 1, 2, 3, 4}; // No!
• C++11 permite inicializar vectores de la STL
mediante listas
Todas las clases estándar de STL ya incluyen
double
d1 = 2.3;
d2 = {4.5};
double d3 {6.7};
double
• Inicializacion mediante listas previene
errores de conversion y truncado
int
int
i1 = 2.3; // Codigo valido
i2 {2.3}; // Genera error
int j{};
// Inicializado a 0
int *p{}; // Inicializado a nullptr
vect1[5] {0, 1, 2, 3, 4};
vector<int> vect2 {5, 6, 7, 8, 9};
vector<string> nombres {“Pedro”, “Juan”,
“Diego”};
esta funcionalidad en C++11
© 2015 Mario Medina C.
4
Tipo de dato auto
Ejemplos de tipo de dato auto
• Tipo de dato auto hace que el compilador
infiera el tipo de una variable de su
inicialización
• Tipo de dato auto
vector<double>::size_type size = notas.size();
size =
notas.size();
puede escribirse como auto
Compilador deduce que size tiene tipo std::
vector<double>::size_type
auto
auto
auto
auto
x
y
z
t
=
=
=
=
5;
5.5;
y;
“H”;
// x tiene tipo int
// y tiene tipo double
// z tiene tipo double
// t tiene tipo
// const char *
vector<int> v[5];
auto b = v[0];
// b tiene tipo int
Recorriendo un vector
Recorriendo un vector usando rangos
• Forma estandar de recorrer un vector
• Ejemplo anterior saca una copia de cada
elemento y luego la descarta
• Para no sacar la copia, o para modificar el
contenido, se puede usar una referencia
int v[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
for (auto i = 0; i != 10; i++)
cout << v[i] << endl;
• Recorriendo un vector usando un rango
for (auto x : v)
// Para todo x en v
cout << x << endl;
Saca una copia de cada elemento en x y luego la descarta
for (auto y : {10, 21, 32, 43, 54, 65})
cout << y << endl;
© 2015 Mario Medina C.
int v[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
for (auto& x : v) // Modifica el vector
++x;
for (auto x : v)
// Imprime 1 a 10
cout << x << endl;
5
Descargar