Saltar al contenido
Topos Uranos

Resumen

Esta clase cierra la sexta unidad del curso, dedicada a los datos compuestos. Reconstruye la cadena de conceptos que va de la secuencia indexada al registro, pasando por la secuencia que crece, el costo de un algoritmo, la búsqueda y el ordenamiento y las tablas; separa lo que de ello vale en cualquier lenguaje de lo que es propio de C++; reúne el comportamiento indefinido de la unidad, con lo que detiene la biblioteca, lo que detiene el detector y lo que no señala nadie; repite en su evaluación de salida las destrezas de la entrada; y termina con seis desafíos que combinan la unidad entera.

Objetivos de aprendizaje

  1. Representar colecciones y entidades con el tipo adecuado (arreglo, vector, tabla o registro), y justificar la elección por la forma de los datos.
  2. Procesar colecciones con algoritmos correctos, escritos a mano y justificados con un invariante, o tomados de la biblioteca respetando sus precondiciones.
  3. Estimar el costo de un algoritmo contando sus operaciones dominantes, y comprobar la estimación con una medida.
  4. Reconocer el comportamiento indefinido de la unidad (el acceso fuera de los límites, la referencia invalidada, el punto medio desbordado, la precondición de la biblioteca violada) y reescribir el programa sin él.
  5. Separar, en lo aprendido en la unidad, lo que vale en cualquier lenguaje de lo que es propio de C++.

Lo logrado en la unidad

La unidad se propuso enseñar a representar colecciones de datos y a procesarlas con los algoritmos básicos, estimando cuánto cuestan. Lo ha logrado apoyándose solo en lo que la introducción declaró por sabido: los bucles con invariante, las funciones y sus modos de paso, la aritmética de los enteros. El programa de los puntajes, que con cinco variables callaba los datos sobrantes, se escribe ahora con un vector; y la pregunta por los empates, que con todos los pares exigía minutos para un millón de datos, se responde ordenando y comparando vecinos.

Arreglos

La clase Arreglos presentó std::array, la secuencia de tamaño fijo, cuyos índices cuentan desde cero porque son desplazamientos. Estableció que el índice ii es válido si y solo si 0≤i<n0 \leq i < n, que cada acceso con [] exige demostrarlo con el invariante del bucle, y que el acceso fuera de los límites es comportamiento indefinido, que .at() convierte en una detención definida; introdujo std::size_t y enseñó a leer los arreglos de C.

Vectores

La clase Vectores presentó la secuencia que crece con push_back y fijó cuándo hace falta guardar una serie: si alguna decisión sobre un dato depende de datos posteriores. Estableció los recorridos canónicos (acumular, filtrar, transformar) con sus invariantes, la regla del paso de un vector, y la diferencia entre tamaño y capacidad, de la que se siguen el costo constante en promedio de push_back y la invalidación de las referencias cuando el vector se muda.

El costo de un algoritmo

La clase El costo de un algoritmo añadió la segunda pregunta: contar la operación dominante en el peor caso, clasificar por el orden de crecimiento, predecir el efecto de duplicar nn y medir con std::chrono::steady_clock, con optimización, sin detectores, repitiendo y tomando la mediana.

Buscar y ordenar

La clase Buscar y ordenar justificó la búsqueda binaria con su invariante y su medida; escribió la selección y la inserción, contando sus comparaciones; presentó los algoritmos de rangos con la precondición del orden, que nadie comprueba; y calculó cuándo conviene ordenar antes de buscar.

Tablas

La clase Tablas recorrió las tablas por filas y por columnas, calculó la traspuesta y el producto de matrices, con su costo cúbico, contó vecinos sin salir de los bordes y guardó una tabla en un vector plano con el índice i⋅columns+ji \cdot \mathit{columns} + j.

Registros

La clase Registros reemplazó los vectores paralelos por el struct, con un valor inicial en cada campo; enseñó a pasar y devolver registros, a ordenarlos y buscarlos por un campo con una proyección, a ordenar por varios criterios con std::ranges::stable_sort y a modelar un problema con registros que contienen registros y vectores.