TECNOLOGÍAS DE LA INFORMACIÓN
LABORATORIO DE ESTRUCTURAS DE DATOS
NÚMERO DE PRÁCTICA: 3.1-02
NOMBRE DE LA PRÁCTICA: APLICACIÓN DE LOS TIPOS DE DATO ABSTRACTO
PILA Y COLA
1. DATOS INFORMATIVOS:
CARRERA: TECNOLOGÍAS DE LA INFORMACIÓN
CICLO/NIVEL: 3ER. SEMESTRE
FECHA: 24/09/2020
DOCENTE RESPONSABLE: ING. FAUSTO REDROVÁN
LABORATORIO: LAB. 2 – HARDWARE Y SOFTWARE
2. FUNDAMENTACIÓN
Pilas
Las pilas son estructuras de datos lineales, denominadas así, porque consisten en una
secuencia de elementos a0, a1, ..., an-1 dispuestos en una dimensión. Dependiendo del
tipo de elementos que queramos almacenar, podremos tener distintos tipos de pilas. Así,
tendremos pilas de enteros, de caracteres, etc, pudiendo tener también pilas de otros
TAD’s.
Dentro de las estructuras lineales, las pilas también se conocen como estructuras LIFO
(Last In, First Out). El nombre LIFO hace referencia al modo en que se accede a los
elementos, ya que todas las inserciones y supresiones tienen lugar en un extremo
denominado tope o cima [1].
TECNOLOGÍAS DE LA INFORMACIÓN
Implementación de la clase Pila (de enteros)
Deseamos crear una clase PilaEnt que represente al TAD Pila de enteros.
Las operaciones de acceso a la pila serán las definidas por el TAD y estarán presentes en
la parte pública de la clase, siendo las mismas en el caso estático y en el caso dinámico:
Pila ();
Constructor de la clase. Inicia la pila a vacía.
boolean pilaVacia();
Comprobación de si hay o no elementos en la pila.
void apilar(int x);
Apilará ‘x’ en la cima de la pila.
int desapilar();
Si hay elementos en la pila, devolverá el valor de la cima y eliminará el
elemento. Si no hay elementos en la pila devolverá error.
int cima ();
Si hay elementos en la pila, devolverá el valor que esté en la cima. Si no hay
elementos en la pila devolverá un error.
Expresiones algebraicas
Dada una cierta expresión algebraica, existen básicamente tres formas diferentes de
escribirla, notación prefija, notación infija y notación postfija, en función de la situación
concreta en la que se pongan los operadores respecto de los operandos. Así la expresión
algebraica que representa la suma entre un cierto valor A y otro B se podría poner de la
siguiente forma:
+ A B Notación prefija
A + B Notación infija
A B + Notación postfija
La notación utilizada habitualmente es la infija.
Si observamos un ejemplo adicional de notación infija en la que se utilicen más de un
operador podemos observar que para realizar correctamente la operación tenemos que
conocer una información adicional acerca de los operadores que aparezcan: La prioridad.
Dependiendo de la prioridad del operador, la operación se realizará antes o después,
dando como consecuencia un resultado distinto si variamos la prioridad de los operadores.
Así, en A + B * C, se realizará primero la multiplicación y a continuación la suma. Si
deseamos variar la prioridad, y en consecuencia el orden de evaluación de las
operaciones, hay que añadir una información adicional que son los paréntesis. Si en el
ejemplo deseamos realizar primero la suma deberemos incluirla entre paréntesis (A + B)
* C.
Esta inclusión de paréntesis no es necesaria en notación prefija o postfija.
TECNOLOGÍAS DE LA INFORMACIÓN
En nuestro caso nos centraremos en la notación infija (la notación habitual) y la postfija
(más conveniente para uso interno en el computador).
La conversión entre la expresión en notación infija y postfija se puede realizar de forma
sencilla mediante la utilización de una pila y considerando las prioridades entre los
operadores que aparecen en la expresión.
Por ejemplo, supongamos que queremos pasar la expresión infija A + B * C - D a postfija.
El proceso sería el siguiente:
1. Iniciamos la pila a vacía (pila = <>).
2. Obtenemos el primer elemento de la expresión (A). Como es un operando, pasa
automáticamente a la salida (Salida = “A”).
3. Miramos el siguiente elemento (+). Como es un operador, comparamos su prioridad con
la del último operador de apilado en la pila. Como la pila está vacía, el operador se apila
en la pila (pila = <+>).
4. El siguiente elemento es la B, un operando. Como antes pasa directamente a la salida
(Salida = “A B”).
5. Ahora el elemento es *, un operador. Comparamos su prioridad con la del operador de la
cima de la pila. Como el * es más prioritario que el +, lo apilamos, en espera de obtener la
otra parte de la operación (pila = <+, *>).
6. El siguiente elemento es C. Va directamente a la salida (Salida = “A B C”).
7. Luego tenemos el –. Comparamos su prioridad con la cima de la pila. El ‘–’ tiene menor
prioridad que el *, luego desapilamos el asterisco, que va a la salida (pila = <+>, Salida =
“A B C *”). Comparamos la prioridad del ‘–’ ahora con la de la cima de la pila (que es el
‘+’.) Como la prioridad es la misma, desapilamos el + y va a la salida (Salida = “A B C *
+”.) La pila esta vacía con lo que no podemos seguir comparando y apilamos el ‘–’ (pila =
<–>).
8. El siguiente elemento de la expresión es la D. Va directamente a la salida (Salida = “A B
C * + D”) Como ya no hay más elementos en la expresión, nos limitamos a desapilar todos
los elementos restantes de la pila y los ponemos en la salida (pila = <>, Salida = “A B C *
+ D –”).
El proceso con paréntesis sería similar, pero teniendo en cuenta que un paréntesis abierto
nunca tiene precedencia sobre ningún elemento, de manera que siempre se apila, y el
paréntesis cerrado desapila todos los símbolos hasta encontrar el paréntesis abierto, que
también se desapila. Los paréntesis, no deben salir ya en la expresión postfija.
TECNOLOGÍAS DE LA INFORMACIÓN
Evaluación de una expresión algebraica en notación postfija
Una vez transformada la expresión a notación postfija se realizará un algoritmo que la
evalúe y dé su resultado. La idea básica del algoritmo es ir apilando los operandos y
resultados parciales en una pila e ir desapilándolos a medida que van siendo necesarios
(cuando encontremos en la expresión un cierto operador).
Colas
Las colas son estructuras de datos lineales, denominadas así, porque consisten en una
secuencia de elementos a0, a1, ..., an-1 dispuestos en una dimensión. Dependiendo del
tipo de elementos que queramos almacenar, podremos tener distintos tipos de colas. Así,
tendremos colas de enteros, de caracteres, etc, pudiendo tener también colas de otros
TAD’s. En el caso de la práctica actual se almacenará en la cola una identificación del
avión o vuelo.
Dentro de las estructuras lineales, las colas también se conocen como estructuras FIFO
(First In, First Out). El nombre FIFO hace referencia al modo en que se introducen y se
accede a los elementos, ya que todas las inserciones se realizan por un lugar (fin de cola)
y supresiones tienen lugar en el otro extremo (principio de cola) [2].
Implementación de la clase Cola
Deseamos crear una clase Cola que represente al TAD Cola de Aviones. En este caso
hemos supuesto que el identificador del vuelo será un String, por lo que solamente
almacenaremos en la cola ese identificador (id). El alumno podrá considerar modificar o
ampliar la cantidad de datos almacenados en cada elemento de la cola. En el caso de
representación estática, se preverá un máximo de 100 vuelos (elementos guardados en la
cola).
TECNOLOGÍAS DE LA INFORMACIÓN
En cualquier caso, las operaciones de uso de la cola serán las definidas por el TAD y
estarán presentes en la parte pública de la clase:
Cola ();
Constructor de la clase. El inicio y final de cola están en el mismo sitio y la cola
está vacía.
boolean colaVacia();
Comprobación de si hay o no elementos en la cola.
int primero();
Proporciona el primer elemento de la cola. Si la cola está vacía devuelve error.
void encolar(int id);
Inserta en la cola el vuelo id.
int desencolar();
Si hay elementos en la cola, devuelve el valor de inicio de cola, es decir, el
primer id, y lo sacará de la cola. Si no hay elementos en la cola devolverá error.
En el caso de que el estudiante lo considere necesario se podrían también implementar
otros métodos como:
numElemCola
invertirCola
Ejercicios a trabajar en el laboratorio:
• Realizar un solo programa que pida al usuario una
expresión algebraica compuesta por números enteros (de
uno o más dígitos) y los operadores ‘+’, ‘-‘, ‘*’ y ‘/’, la pase a
notación postfija y la evalúe ayudándose de una pila de
enteros, mostrando por pantalla el paso intermedio
(expresión en notación postfija) y el resultado final.
• Realizar un solo programa de simulación de las colas del
aeropuerto, además de las clases Cola correspondientes.
3. OBJETIVOS:
- Implementar el tipo abstracto de datos TadPila para la evaluación de una expresión
algebraica escrita en notación infija.
- Implementar el tipo abstracto de datos TadCola para su utilización en la simulación de
colas de despegue de aviones de un aeropuerto.
TECNOLOGÍAS DE LA INFORMACIÓN
4. MATERIALES E INSUMOS
- Computadora de escritorio o portátil
- Sistema Operativo Windows o Linux
- JDK 1.8 o superior
- IDE Eclipse o Netbeans
- Red de datos e Internet
- Diseño previo de los algoritmos
5. PROCEDIMIENTO
5.1. Crear el proyecto java en Eclipse: Laboratorio02
5.2. Cargar los TAD Pila y Cola.
5.3. En una clase ExpresionPosFija simular la expresión “13 7 3 * + 5 –” (en infija sería
“13 + 7 * 3 – 5” que tiene como resultado 29). La manera de evaluarla será:
5.3.1. Iniciamos la pila a vacía (pila = <>)
5.3.2. Obtenemos el primer valor.
5.3.3. Como es un entero, lo apilamos (pila = <13>)
5.3.4. Obtenemos el segundo elemento y el tercero, que también son enteros y los
apilamos (pila = <13, 7, 3>)
5.3.5. Obtenemos el siguiente elemento que es un ‘*’. Como es un operador,
necesitamos obtener los dos operandos involucrados que son los dos últimos de
la pila, el 3 y el 7 que desapilamos. Los operamos con el * y obtenemos 21. El
valor 21 lo apilamos (pila = <13, 21>)
5.3.6. El siguiente elemento es el +. Necesita de nuevo dos operandos que serán los
dos últimos de la pila, el 21 y el 13, que desapilamos. Los operamos con + y
apilamos el resultado (pila = <34>)
5.3.7. Después obtenemos el 5 en la expresión. Lo apilamos (pila = <34, 5>)
5.3.8. Finalmente obtenemos de la expresión el ‘–’. Desapilamos el 5 y el 34, restamos
(34-5=29) y apilamos el resultado (pila = <29>)
5.3.9. Como ya hemos llegado al final de la expresión, el resultado de la operación es
lo que esté en la cima de la pila.
Notas:
- Si en algún momento nos quedamos sin operandos en la pila cuando es
necesario desapilar dos elementos, se ha producido un error.
- Si al finalizar el proceso, queda más de un elemento en la pila también se ha
producido un error.
- En ambos casos la expresión estaba mal escrita.
5.4. Simulación de colas de despegue de un aeropuerto: vamos a tratar de simular las
colas de despegue de un aeropuerto. Para ello se deberá implementar una clase
ColaVuelos donde los datos guardados dentro de la cola será como mínimo un
identificador del vuelo.
TECNOLOGÍAS DE LA INFORMACIÓN
5.5. Los identificadores válidos están formados por 2 caracteres iniciales con letras
mayúsculas, que corresponden a la compañía y 4 caracteres numéricos que
corresponden al número de vuelo. Ejemplos: IB0012, LH8892, AF1251.
5.6. Deberá desarrollar un programa que simulará las colas de despegue del aeropuerto
usando la clase cola previamente definida.
5.7. En este programa se va a simular el flujo de salida de aviones en un aeropuerto. El
funcionamiento de las salidas es el siguiente:
5.7.1. Entre un despegue y el siguiente se debe esperar un tiempo determinado: 10
segundos
5.7.2. Cuando un avión esté en la cola de despegue y sea el que tiene el turno para
despegar, se recurrirá a una función que identifique si el avión tiene problemas
para despegar o no.
5.7.3. Para ello esta función de “problema de despegue” deberá considerar
aleatoriamente que el 10% de los aviones que van a despegar sufren retrasos.
5.7.4. Si la función “problema de despegue” indica que el avión concreto que se
encuentra en el inicio de la cola está entre los del 10% que tienen problemas, no
despegará. Se sacará de la cola y se pondrá en el final de la cola para poder
volver a intentar despegar cuando le toque otra vez.
5.7.5. Si al introducir un avión en la cola, hace más de diez segundos que despegó el
último, este despega directamente sin hacerle esperar, sin esperar el tiempo
restante hasta los diez segundos que deben transcurrir entre un vuelo y el
siguiente.
5.8. Monitorización de vuelos por pantalla: El programa podrá estar en cualquiera de los 3
siguientes estados:
- Introducir vuelos nuevos en la cola de despegue
- Ver estado de vuelos
- Pasar un segundo
Que se podrán seleccionar desde un menú.
5.9. Para introducir un nuevo vuelo en la cola de salida, se pasará al modo 1 de trabajo
en el que se permitirán introducir vuelos pedirá el identificador de vuelo por teclado, y
si éste es válido se introducirá en la cola de salida.
5.10. Cuando sea introducido en la cola de salida y se pase al modo 2 se mostrará
por pantalla el siguiente mensaje:
“Vuelo ident_vuelo ->salida prevista en min:segs”.
Ejemplo: Vuelo LH0889 -> salida prevista en 03:15
5.11. Cuando un vuelo consiga despegar se mostrará el siguiente mensaje:
“ident_vuelo despegando”.
5.12. Para simular el 10% de vuelos que tiene problemas de despegue y no
consiguen despegar cuando les toca, utilizaremos una función que de forma aleatoria
nos diga si el vuelo despega o no. Así cuando a un vuelo le toque despegar, se llamará
a esta función, que devuelve “true” en caso de que tenga problema de despegue y
“false” en caso de que pueda despegar:
5.12.1. Si devuelve false. El vuelo despegará, con lo cual, el vuelo será extraído de la
cola de despegue”, y se mostrará el mensaje indicado anteriormente en pantalla.
TECNOLOGÍAS DE LA INFORMACIÓN
5.12.2. Si devuelve true. El vuelo no despegará, con lo cual, se extraerá del inicio de
la cola y se insertará al final, dando el mensaje:
“vuelo ident_vuelo con problemas, nueva previsión de salida en min:segs”
5.12.3. Además se insertará el vuelo en otra cola en la que se guardarán los vuelos
que han tenido problemas en el despegue.
5.13. El paso del tiempo lo supondremos por selección de menú. Cada vez que el
usuario seleccione una opción del menú, supondremos que pasa un segundo.
5.14. El programa finaliza cuando el usuario pulse una tecla o botón de fin, pero antes
de finalizar mostrará por pantalla la siguiente información:
- Número de vuelos que consiguieron despegar,
- Despliegue por pantalla la cola de vuelos que queden por despegar, (si quedan)
- Despliegue por pantalla la cola de vuelos que tuvieron problemas en el despegue,
(si los hubo)
6. CUADROS DE RESULTADOS
El diagrama de clases y código de los programas
Capturas de las pantallas de salida.
7. CONCLUSIONES (Orientación para el informe)
Concluir tomando en cuenta las diferentes pruebas que se hicieron al programa y las
siguientes preguntas: ¿Qué pasa si el usuario no ingresa un número entero o
correctamente los operadores? ¿Qué pasa si el usuario no ingresa correctamente la
identificación del vuelo?
8. RECOMENDACIONES (Orientación para los informes)
Para sus recomendaciones tome en cuenta las siguientes preguntas: ¿Se puede controlar
lo que ingresa el usuario?
9. BIBLIOGRAFÍA
[1] L. Joyanes Aguilar, Estructuras de Datos en Java, Cuarta ed., Madrid: McGraw Hill,
2008.
[2] L. Joyanes Aguilar, Fundamentos de Programación. Algoritmos, estructura de datos
y objetos., Madrid: McGraw Hill, 2008.