Ejercicios de Estructuras
1.1 Ejercicio ejemplo
El Rally Dakar es una carrera que consta de 15 etapas en la que participan vehículos de
diversas categorías (coches, motos, camiones, etc.).
Disponemos de un fichero de texto que almacena los resultados obtenidos por cada
piloto y etapa. Cada línea de este fichero contiene los siguientes datos, separados por el
carácter ’#’: nombre del piloto, categoría en la que participa, numero de etapa (entero
entre 1 y 15) y tiempo empleado en dicha etapa expresado en minutos (numero
flotante).
A continuación se muestran algunas líneas de ejemplo:
sainz#coches#2#124.23
peterhansel#coches#2#130.15
coma#motos#2#150.20
esteve#motos#1#57.21
esteve#motos#2#129.87
vatanen#coches#1#58.03
coma#motos#3#220.41
sainz#coches#1#55.99
peterhansel#coches#1#55.90
vatanen#coches#2#123.56
esteve#motos#3#205.10
sainz#coches#3#209.34
coma#motos#1#135.00
Ten en cuenta que es frecuente que durante la carrera se produzcan abandonos, y que el
fichero sólo contiene información de las etapas que cada piloto ha terminado.
Implementa en Python:
a) Una función que reciba como parámetros el nombre del fichero que contiene la
información de la carrera y el nombre de una categoría, y construya y devuelva una lista
de registros que resuma la información de la categoria dada. En concreto, cada registro
debe contener el nombre de un piloto y una lista con los tiempos que ha empleado en
cada una de las 15 etapas. Indica como representas en esta lista el hecho de que un
piloto haya abandonado la carrera a partir de una cierta etapa.
Importante: No se permite leer el fichero dado más de una vez.
b) Una función que reciba como parámetros una lista como la obtenida en el apartado
anterior y un número de etapa (valor de 1 a 15), y devuelva el nombre del piloto que
lideraba la clasificación general en esa etapa. El líder de la clasificación general en una
etapa es el piloto que ha empleado en la carrera un menor tiempo acumulado hasta dicha
etapa. Ten en cuenta que no debes considerar a los pilotos que hayan abandonado la
carrera antes del final de la etapa dada.
c) Un procedimiento que reciba como parámetro una lista como la obtenida en el primer
apartado, y muestre por pantalla el nombre del vencedor de cada una de las etapas. El
vencedor de una etapa será el piloto que haya empleado el menor tiempo en completar
dicha etapa.
Se valorara que la solución de esta función recorra la lista de registros dada una sola vez
1.2 Ejemplo propuesto
Vamos a hacer un ejemplo completo que use tablas (“arrays”), registros (“struct”) y que
además manipule cadenas.
La idea va a ser la siguiente: Crearemos un programa que pueda almacenar datos de
hasta 1000 ficheros. Para cada fichero, debe guardar los siguientes datos: Nombre del
fichero (max 40 letras), Tamaño (en KB, número de 0 a 2.000.000.000). El programa
mostrará un menú que permita al usuario las siguientes operaciones:
1- Añadir datos de un nuevo fichero
2- Mostrar los nombres de todos los ficheros almacenados
3- Mostrar ficheros que sean de más de un cierto tamaño (por ejemplo, 2000 KB).
4- Ver todos los datos de un cierto fichero (a partir de su nombre)
5- Salir de la aplicación (como no usamos ficheros, los datos se perderán).
No debería resultar difícil. Vamos a ver directamente una de las formas en que se podría
plantear y luego comentaremos alguna de las mejoras que se podría (incluso se debería)
hacer.
Una opción que podemos a tomar para resolver este problema es la de contar el número
de fichas que tenemos almacenadas, y así podremos añadir de una en una. Si tenemos 0
fichas, deberemos almacenar la siguiente (la primera) en la posición 0; si tenemos dos
fichas, serán la 0 y la 1, luego añadiremos en la posición 2; en general, si tenemos “n”
fichas, añadiremos cada nueva ficha en la posición “n”. Por otra parte, para revisar todas
las fichas, recorreremos desde la posición 0 hasta la n-1, haciendo algo como
for (i=0; i<=n-1; i++) { ... más órdenes ...}
o bien algo como
for (i=0; i<n; i++) { ... más órdenes ...}
El resto del programa no es difícil: sabemos leer y comparar textos y números. Sólo
haremos tres consideraciones:
* Los textos (nombre del fichero, por ejemplo) pueden contener espacios, por lo que
usaremos “gets” en vez de “scanf”.
* Es “peligroso” mezclar órdenes “gets” y “scanf”: si leemos un número con “scanf”, la
pulsación de la tecla “Intro” posterior se queda en el buffer del teclado, lo que puede
provocar que después intentemos leer con “gets” un texto, pero sólo leamos esa
pulsación de la tecla “Intro”. Para evitarlo, los números los leeremos “en dos etapas”:
primero leeremos una cadena con “gets” y luego la convertiremos a número con
“sscanf”.
* Hemos limitado el número de fichas a 1000, así que, si nos piden añadir, deberíamos
asegurarnos antes de que todavía tenemos hueco disponible.
En la medida de lo posible, comenta el código y utiliza funciones.
La solución del ejercicio la tienes en: /ejercicio_resuelto/ejercicio.1.2/resolucion.c
1.3 Ejemplo propuesto
Un programa que pida el nombre, el apellido y la edad de una persona, los
almacene en un “struct” y luego muestre los tres datos en una misma línea,
separados por comas.
Un programa que pida datos de 8 personas: nombre, dia de nacimiento, mes de
nacimiento, y año de nacimiento (que se deben almacenar en una tabla de
structs). Después deberá repetir lo siguiente: preguntar un número de mes y
mostrar en pantalla los datos de las personas que cumplan los años durante ese
mes. Terminará de repetirse cuando se teclee 0 como número de mes.
Un programa que sea capaz de almacenar los datos de 50 personas: nombre,
dirección, teléfono, edad (usando una tabla de structs). Deberá ir pidiendo los
datos uno por uno, hasta que un nombre se introduzca vacío (se pulse Intro sin
teclear nada). Entonces deberá aparecer un menú que permita:
o Mostrar la lista de todos los nombres.
o Mostrar las personas de una cierta edad.
o Mostrar las personas cuya inicial sea la que el usuario indique.
o Salir del programa
(lógicamente, este menú debe repetirse hasta que se escoja la opción de
“salir”).