C++ ofrece distintos contenedores para almacenar elementos del mismo tipo de forma ordenada.
Existe std::array para contenedores de tamaño fijo y std::vector, que incorpora capacidades de redimensionamiento dinámico.
Cuando declaras un array o un vector, tienes que especificar el tipo de elementos que contendrá el contenedor. Los arrays también necesitan un tamaño. Fíjate en estos ejemplos para ver cómo se inicializan los dos tipos de contenedor:
#include <array>
#include <string>
// std::array<element_type, size> variable_name {list of elements}
std::array<std::string, 3> indie_rock {"yeah", "yeah", "yeah"};
// indie_rock contains the elements "yeah" three times
Los vectores suelen necesitar más espacio, ya que reservan memoria para seguir creciendo. No necesitas especificar un tamaño:
#include <vector>
// std::vector<element_type> variable_name {list of elements}
std::vector<int> countdown {3, 2, 1};
// countdown contains the elements 3, 2 and 1
Nota: todavía no necesitas conocer la mecánica exacta que hay detrás del concepto de plantilla; tendrá su propio concepto más abajo en el árbol del temario.
Los vectores y los arrays comparten las mismas funciones para acceder a sus elementos.
Puedes usar las funciones miembro front y back para obtener el primer y el último elemento del contenedor.
También dispones de at y del operador [] para acceder a elementos concretos.
countdown[0];
// => 3
countdown.at(2);
// => 1
countdown[1] = 4;
// countdown now contains 3, 4 and 1
indie_rock.back() = "yeahs";
// indie_rock is now "yeah", "yeah", "yeahs"
Nota: si eliges una posición que no está dentro del rango de tu contenedor,
[]puede provocar un comportamiento indefinido. La funciónatlanzaría una excepción, lo que a la larga podría facilitarte la vida.
Como un vector no tiene un tamaño fijo, es posible añadir o eliminar elementos.
Dos funciones habituales para ello son emplace_back y pop_back.
std::vector<std::string> witches {"Holly", "Alyssa", "Shannen"};
witches.pop_back();
// Shannen is no longer with the witches
witches.emplace_back("Rose");
// Rose has joined the team
Puedes comprobar si un contenedor está vacío con la función miembro empty.
Si quieres saber el número de elementos, puedes usar size.
Eres ayudante de un profesor y estás corrigiendo los exámenes de los estudiantes. Llevar un registro manual de los resultados se está volviendo tedioso y propenso a errores. Decides hacerlo un poco más interesante creando unas cuantas funciones para contar y calcular los resultados de la clase.
Aunque puedes dar «puntuación parcial» en las preguntas del examen, las puntuaciones totales del examen tienen que ser ints.
Así que, antes de poder hacer cualquier otra cosa con las puntuaciones de la clase, tienes que repasar las notas y convertir en int las puntuaciones que sean double.
Crea la función round_down_scores(), que recibe un vector de student_scores.
El redondeo que piden las escuelas es un truncamiento.
Por suerte para ti, C++ puede convertir un tipo en otro con static_cast.
La conversión con static_cast de double a int descarta todos los dígitos que quedan después del separador decimal.
Esta función debe recibir el vector de entrada y return un vector nuevo con todas las puntuaciones convertidas a ints.
std::vector<double> student_scores {90.33, 40.5, 55.44, 70.05, 30.55, 25.45, 80.45, 95.3, 38.7, 40.3};
round_down_scores(student_scores)
// => {90, 40, 55, 70, 30, 25, 80, 95, 38, 40}
Hay otros métodos que logran el mismo resultado, pero un cast es algo que se ve con frecuencia.
int new_PI{static_cast<int>(3.14) + static_cast<int>(0.001592653589)};
// new_PI is 3.
Mientras corregías el examen, te diste cuenta de que algunos estudiantes no lo estaban haciendo tan bien como esperabas. Pero te distrajiste y olvidaste anotar exactamente cuántos estudiantes eran.
Crea la función count_failed_students(), que recibe un vector de student_scores.
Esta función debe contar el número de estudiantes que no han aprobado y devolver ese recuento como un número entero.
Un estudiante necesita una puntuación mayor que 40 para aprobar el examen.
count_failed_students({90,40,55,70,30,25,80,95,38,40});
// => 5
Al profesor al que ayudas le gusta asignar calificaciones con letra además de puntuaciones numéricas. Como es raro que los estudiantes saquen un 100 en un examen, los umbrales inferiores de las «calificaciones con letra» se calculan a partir de la puntuación más alta obtenida y aumentan de forma uniforme entre esa puntuación máxima y el umbral de suspenso de <= 40.
Crea la función letter_grades(), que recibe como parámetro la puntuación «más alta» del examen y devuelve un array (no un vector) con los umbrales inferiores de puntuación para cada intervalo de calificación «estilo estadounidense»: ["D", "C", "B", "A"].
/*Where the highest score is 100, and failing is <= 40.
"F" <= 40
41 <= "D" <= 55
56 <= "C" <= 70
71 <= "B" <= 85
86 <= "A" <= 100
*/
letter_grades(100);
// => {41, 56, 71, 86}
/*Where the highest score is 88, and failing is <= 40.
"F" <= 40
41 <= "D" <= 52
53 <= "C" <= 64
65 <= "B" <= 76
77 <= "A" <= 88
*/
letter_grades(88);
// => {41, 53, 65, 77}
Tienes las puntuaciones del examen en orden descendente y los nombres de los estudiantes correspondientes (ordenados según sus puntuaciones en el examen). Te gustaría emparejar el nombre de cada estudiante con su puntuación en el examen e imprimir una clasificación general de la clase.
Crea la función student_ranking() con los parámetros student_scores y student_names.
Empareja cada nombre de estudiante del vector student_names con su puntuación del vector student_scores.
Puedes dar por hecho que cada vector de argumentos está ordenado de la puntuación más alta a la más baja.
La función debe devolver un vector de strings con el formato <rank>. <student name>: <student score>.
std::vector<int> student_scores {100, 99, 90, 84, 66, 53, 47};
std::vector<std::string> student_names {"Joci", "Sara","Kora","Jan","Indra","Bern", "Fred"};
student_ranking(student_scores, student_names)
// =>
// {"1. Joci: 100", "2. Sara: 99", "3. Kora: 90", "4. Jan: 84", "5. Indra: 66", "6. Bern: 53", "7. Fred: 47"}
Aunque una puntuación «perfecta» de 100 es rara en un examen, es interesante saber si al menos un estudiante la ha conseguido.
Crea la función perfect_score() con los parámetros student_scores y student_names.
Los arrays son los mismos que en la tarea 4.
La función debe return el primer <name> (como string) del estudiante que sacó un 100 en el examen.
Si no se encuentra ninguna puntuación de 100, debe devolverse un string vacío "".
perfect_score({"Nur", "Tony", "Fatima"}, {90, 80, 100});
// => "Fatima"
perfect_score({"Nur", "Tony"}, {90, 80});
// => ""
Regístrate en Exercism para aprender y dominar C++ con 19 conceptos100 ejercicios y mentoría humana real, todo gratis.