Cap.11 - Colas - Ejercicio 11.2

Anuncio
Cap 11. Apartado 11.5.1, página 358-362
EJERCICIO 11.2
La salida a pista de las avionetas de un aeródromo está organizada en forma de
fila(línea), con una capacidad máxima de aparatos en espera de 13 avionetas. Las
avionetas llegan por el extremo
izquierdo y salen por el extremo derecho. Un piloto
puede decidir retirarse de la fila por razones técnicas, en ese caso todas las avionetas a su
derecha han de ser retiradas, retirar el aparato y las avionetas desplazadas colocarlas de
nuevo en el mismo orden relativo en que estaban. La salida de una avioneta de la fila
supone que las demás son movidas hacia adelante, de tal forma que los espacios libres del
estacionamiento estén en la parte izquierda.
El programa para emular este estacionamiento tiene como entrada un carácter
que indica una acción sobre la avioneta, y la matrícula de la avioneta. La acción puede
ser llegada(E), salida(S) de la avioneta que ocupa la primera posición y retirada (T) de
una avioneta de la fila . En la llegada puede ocurrir que el estacionamiento esté lleno, si
esto ocurre la avioneta espera hasta que se quede una plaza libre.
El estacionamiento va a estar representado por una bicola de salida restringida. ¿Por qué
esta elección?, la salida siempre se hace por el mismo extremo, sin embargo la entrada se
puede hacer por los dos extremos, y así contemplar dos acciones: que llegue una avioneta
nueva; y que tenga que entrar una avioneta que ha sido movida para que salga una
intermedia.
Las avionetas que se mueven para poder retirar del estacionamiento una intermedia, se
disponen en una lista LIFO, así la ultima en entrar será la primera en añadirse en el
extremo salida del estacionamiento (bicola) y seguir en el mismo orden relativo.
Las avionetas se pueden representar mediante una cadena para almacenar el número de
matrícula (tipo avioneta). Los elementos de la pila y de la bicola son del tipo avioneta.
La lista LIFO es en realidad una pila. La codificación de las operaciones sobre pilas se
encuentran el el capítulo 10, ahora simplemente se incluye el archivo pila.h .
Las operaciones del TAD Bicola
se realizan considerando el almacenamiento de los
elementos en un array circular. La restricción de salida se refleja en que no es válida la
operación quitarIzqda. Los extremos de la estructura se denominan entrada y salida, de
tal forma que son índices de las avionetas que menos tiempo lleva en la fila y que mas
tiempo lleva respectivamente. En el archivo bicolacircular.h se encuentran los tipos
de datos y los prototipos de las operaciones. Los tipos y constantes:
#define MAXTAMQ 14
typedef struct
{
TipoDato listaBicola[MAXTAMQ];
int salida, entrada;
}Bicola;
A continuación se presenta el archivo con la implementación de las operaciones mas
importantes. Para mover circularmente los índices hacia delante y hacia atrás se codifican
las funciones siguiente() y anterior() respectivamente.
Codificación del TAD Bicola
typedef struct
{
char matricula[51];
} Avioneta;
typedef Avioneta TipoDato;
#include “bicolacircular.h”
int siguiente(int n)
{
return (n + 1) % MAXTAMQ;
}
int anterior(int n)
{
/* anterior de 0 es el índice mas alto */
return ((n-1) < 0) ? MAXTAMQ-1 : n-1;
}
void crearBicola(Bicola* bicola)
{
bicola -> salida = 0;
bicola -> entrada = MAXTAMQ-1;
}
void inserIzqda(Bicola* bicola, TipoDato avta)
{
if (!bicolaLlena(*bicola))
{
bicola -> entrada = siguiente(bicola->entrada);
bicola -> listaBicola[bicola->entrada] = avta;
}
}
void inserDrcha(Bicola* bicola, TipoDato avta)
{
if (!bicolaLlena(*bicola))
{
bicola -> salida = anterior(bicola->salida);
bicola -> listaBicola[bicola->salida] = avta;
}
}
TipoDato quitarIzqda(Bicola* bicola)
{
TipoDato tmp;
if (bicolaVacia(*bicola))
{
puts(" Extracción por entrada en bicola vacía ");
exit (1);
}
tmp = bicola -> listaBicola[bicola->entrada];
/* retrocede el índice entrada */
bicola -> entrada = anterior(bicola->entrada);
return tmp;
}
TipoDato quitarDrcha(Bicola* bicola)
{
TipoDato tmp;
if (bicolaVacia(*bicola))
{
puts(" Extracción en bicola vacía ");
exit (1);
}
tmp = bicola -> listaBicola[bicola->salida];
/* avanza el índice salida */
bicola -> salida = siguiente(bicola->salida);
return tmp;
}
int bicolaVacia(Bicola bicola)
{
return bicola.salida == siguiente(bicola.entrada);
}
int bicolaLlena(Bicola bicola)
{
return
bicola.salida
siguiente(siguiente(bicola.entrada));
}
==
Codificación de la función principal
En el archivo fuente con la función principal se codifica la simulación a realizar. Se
incorpora la función posicion() que determina la posición que ocupa una avioneta en la
fila. También, la operación retirar() que simula el hecho de que una avioneta que se
encuentra en cualquier posición de la bicola decide salir de la fila; esta función hace uso
del TAD Pila para guardar las avionetas que temporalmente tienen que apartarse de la fila
para que pueda salir la avioneta en cuestión.
typedef struct
{
char matricula[51];
} Avioneta;
typedef Avioneta TipoDato;
#include “bicolacircular.h”
#include "pila.h"
#include <ctype.h>
#include <stdio.h>
int posicion(Bicola bicola, Avioneta av);
int retirar(Bicola* bicola, Avioneta av);
void main()
{
Avioneta u;
char ch;
Bicola fila;
int esta, mas = 1;
crearBicola(&fila);
while (mas)
{
puts(“\n
Entrada
de
datos:
[acción:
matrícula.”);
puts(“ Para terminar la simulación: X.”);
E/S/T]
do {
scanf(“%c%*c”,&ch); ch = tolower(ch);
} while(ch != ‘e’ && ch != ‘s’ && ch != ‘t’ && ch !=
‘x’);
if (ch == ‘s’)
{
if (!bicolaVacia(fila))
{
u = quitarDrcha(&fila);
printf(“Salida
de
la
avioneta:
%s”,
u.matricula);
}
}
else if (ch == ‘e’)
{
if (!bicolaLlena(fila))
{
gets(u.matricula);
inserIzqda(&fila, u);
}
}
else if (ch == ‘t’)
{
if (!bicolaLlena(fila))
{
gets(u.matricula);
esta = retirar(&fila, u);
if (!esta) puts(“Error de datos, avioneta
no encontrada”);
}
}
mas = !(ch == ‘x’);
}
}
int posicion(Bicola bicola, Avioneta a)
{
int p, encontrada;
p = anterior(bicola.salida);
encontrada = 0;
while (!encontrada && p != bicola.entrada)
{
p = siguiente(p);
encontrada = strcmp(bicola.listaBicola[p].matricula,
a.matricula) == 0;
}
if (encontrada)
return p;
else
return –1;
}
int retirar(Bicola* bicola, Avioneta av)
{
int p;
p = posicion(*bicola, av);
if (p == -1)
error no está la avioneta */
return 0;
else
{
Pila pila
/*
if (p == bicola->salida) /* está en el extremo de
salida */
quitarDrcha(bicola);
else
{
/*
se
meten
en
la
pila
los
elementos
siguientes a p */
crearPila(&pila);
do {
insertar(&pila, quitarDrcha(bicola));
} while (bicola->salida != p);
printf(“Avioneta %s es retirada \n”,
quitarDrcha(bicola).matricula);
/* elementos de la pila se meten de nuevo
en la fila */
while (!pilaVacia(pila))
{
inserDrcha(bicola,quitar(&pila));
}
}
return 1;
}
}
/* operación realizada */
Descargar