Вы находитесь на странице: 1из 5

UNIVERSIDAD AUTNOMA DE MADRID

INGENIERA DE TELECOMUNICACIN
ASIGNATURA: ESTRUCTURA DE DATOS Y ALGORITMOS

PRCTICA 2: PILAS

REALIZACIN Y ENTREGA DE LA PRCTICA:


Realizacin Turno A: 21/3 y 11/4/2007, Entrega Turno A: 18/4/2007.
Realizacin Turno B: 22/3 y 12/4/2007, Entrega Turno B: 19/4/2007.
Realizacin Turno C: 22/3 y 12/4/2007, Entrega Turno C: 19/4/2007.

OBJETIVOS Y PRESENTACIN:
El objetivo de esta prctica es implementar el tipo abstracto de datos (TAD) PILA y
abordar un problema de aplicacin de dicho tipo de datos. El problema consistir en
programar la resolucin de laberintos: dado que el algoritmo bsico para resolver un
laberinto consiste en ir probando movimientos y volver atrs cuando ya no hay salida
desandando el ltimo movimiento, se presta a la utilizacin de una pila pues lo que hay
que hacer es ir almacenando los movimientos que se han efectuado e ir recuperndolos
en orden inverso, es decir siguiendo el orden LIFO (Last In First Out). La
implementacin del tipo de dato ser una implementacin genrica, es decir no
dependiente del tipo de elemento que se va a guardar en la pila. Se va a utilizar el tipo
de pila esttica. Esto quiere decir que el espacio que reserva el dato para almacenar los
elementos es de un tamao dado que no se modifica posteriormente. Ntese que esto no
quiere decir que dicho espacio no pueda reservarse dinmicamente (mediante malloc),
sino que es un tamao que una vez asignado no se modifica (y la pila devuelve error si
se intenta rebasar dicho tamao).
MEMORIA A PRESENTAR:
Cada equipo conformado deber enviar por la Web para entrega de prcticas de la
asignatura EDA el cdigo fuente (archivos .c), los archivos cabeceras (archivos .h) y
opcionalmente los archivos .dsp y .dsw correspondientes a cada uno de los cuatro
problemas. Los archivos de todas las carpetas (una carpeta por problema) deben
comprimirse segn normas establecidas en la Web de la asignatura. Adicionalmente,
debe entregarse una documentacin (memoria) en la que se describa brevemente la
resolucin del problema realizada y se adjunte el cdigo impreso de los distintos
programas junto con los aspectos de equipo especificados en la Web de la asignatura.
NORMAS BSICAS:
Las siguientes normas deben ser consideradas en la realizacin de la solucin a los
problemas propuestos y la entrega del material:
1. Estilo de programacin: debe ajustarse a las normas de programacin definidas
para el curso (pueden consultarse en la Web).
2. Pruebas: es especialmente importante el control de errores; es justificable que
un programa no admita valores muy grandes de los datos, pero no es justificable

1
que el programa tenga un comportamiento anmalo con dichos valores. Los
ejecutables deben de haberse compilado con el Visual C++, y deben de poder
ejecutarse en una sesin DOS de Windows 98 o superior.
3. Nombre de los archivos: debe ser de la forma P2n_xxx.c, siendo n el nmero de
problema (1, 2, 3 4) y xxx el cdigo de turno (A, da mircoles; B, da jueves a
la tarde; C, da jueves a la maana) y el nmero de equipo.
4. Base de calificacin: si bien se incluyen en la prctica un par de problemas
auxiliares para comprobar la implementacin del TAD PILA, la calificacin de
la prctica estar basada principalmente en la resolucin del Problema 4.
5. Prototipos para el cdigo fuente y ejemplos de laberintos .

PROBLEMAS:

PROBLEMA 1:
Implementar las funciones bsicas del TAD PILA. Dichas funciones estn definidas en el
archivo pila.h que se adjunta, y son las siguientes:

ESTADO InicializaPila(PILA *pila): reserva memoria para la tabla o array de datos de la pila,
devuelve error si no ha conseguido alocar memoria.

BOOLEANO PilaVacia(PILA *pila): indica si la pila est o no vaca.

BOOLEANO PilaLlena(PILA *pila): indica si la pila est o no llena.

ESTADO Poner(PILA *pila, TIPO_INFO_PILA dato): introduce un elemento en la pila, devuelve error si
no ha sido posible (la pila est llena).

ESTADO Sacar(PILA *pila, TIPO_INFO_PILA *dato): saca un elemento de la pila, devuelve error si no
ha sido posible (la pila est vaca).

void LiberaPila(PILA *pila): libera la memoria alocada para el array interno de datos de la pila.

En dicho archivo se incluye a su vez dos archivos auxiliares en los que se definen tanto los tipos
de datos TIPO_INFO_PILA (infopila.h) as como ESTADO y BOOLEANO (tipos.h). El tipo de
datos TIPO_INFO_PILA se define inicialmente como char, es decir los elementos de la pila en
esta primera implementacin sern caracteres, pero cambiando la definicin de infopila.h puede
tenerse una pila en la que los datos sean de cualquier otro tipo. La implementacin de las
funciones del TAD PILA debe realizarse en un archivo de nombre pila.c.

PROBLEMA 2:
Escribir un programa de prueba para comprobar el funcionamiento adecuado de la
implementacin del tipo de datos PILA. El programa debe recibir como argumento por la lnea
de comandos una cadena de caracteres e imprimir por pantalla dicha cadena al revs. Para ello
debe introducir todos los caracteres en la pila y sacarlos seguidamente (en orden inverso). A
continuacin, el programa imprimir los caracteres de la cadena ordenados de menor a mayor
(por orden alfabtico, o cdigo ASCII); para ello deber utilizarse una segunda pila auxiliar, y
proceder de acuerdo al siguiente algoritmo: se van introduciendo los caracteres en la pila
principal, y para cada nuevo carcter se empiezan a sacar caracteres de la pila y pasarlos a la

2
pila auxiliar hasta encontrar uno mayor que el nuevo, se inserta el carcter nuevo en la pila
principal y se recuperan los caracteres de la pila auxiliar a la pila principal; de esta forma se
puede insertar el carcter nuevo en la posicin adecuada.
El cdigo fuente del programa principal deber estar en un archivo diferente al de las funciones
del TAD PILA, debiendo generarse un proyecto con el Visual C++ para generar un ejecutable a
partir de dos archivos. Es importante tambin que la utilizacin de la pila se realice a travs de
las funciones definidas en el problema 1, y no a travs de acceso directo a los miembros de la
estructura de datos.

PROBLEMA 3:
Modificar el archivo infopila.h, de forma que el TIPO_INFO_PILA sea ahora un char *.
Modificar el programa del problema 2 para que realice sus funciones con palabras en lugar de
caracteres.

PROBLEMA 4:
Programacin del algoritmo de resolucin de laberintos. Para ello se codificar un laberinto
como una matriz en la que cada casilla puede estar vaca (' ') o ocupada por un muro ('*'); existe
tambin una casilla de entrada ('E') y otra de salida ('S'). Los laberintos tendrn siempre forma
rectangular, y se escribirn en archivos de texto, teniendo por lo tanto que escribirse una funcin
para leer el archivo y volcarlo a la estructura de datos correspondiente.
En dicho archivo el principio y final de cada lnea se indicar mediante el carcter |. Dicho
carcter no formar parte del laberinto, y debern ignorarse tambin los caracteres ms all del
separador, as como las lneas que no incluyan los dos separadores. De esta forma se evitarn
confusiones con espacios en blanco o saltos de lnea. La definicin de dicha estructura y de las
funciones necesarias se encuentra en el archivo laberinto.h, y las reproducimos a continuacin.
Nota: no es necesario que en los bordes del laberinto haya un muro (*), de hecho un laberinto
todo blanco excepto por las casillas de entrada y salida es vlido. Eso s, el algoritmo de
recorrido debe comprobar que no se accede a posiciones de coordenada negativa (chequeo de
contorno).

typedef enum { NINGUNO, ARRIBA, ABAJO, DERECHA, IZQUIERDA } MOVIMIENTO;

La definicin de este tipo de datos se encuentra en el archivo movimiento.h.


El archivo infopila.h deber modificarse nuevamente para este problema, de forma tal que ahora
el TIPO_INFO_PILA sea MOVIMIENTO (por lo que infopila.h deber incluir a movimiento.h).

#define LADO_MAX 100

typedef struct { char mapa[LADO_MAX][LADO_MAX]; int ancho; int alto; } LABERINTO;

/* definicin del tipo laberinto */

typedef struct { int x; int y; } COORDENADA;

ESTADO lee_laberinto(char *nombre_fichero, LABERINTO *laberinto, COORDENADA


*posicion_entrada): se encarga de volcar los datos desde el fichero a la estructura laberinto.
Adems, devuelve las coordenadas x e y de la entrada al laberinto. Da ERROR, si hay algn
problema.

void imprime_laberinto(LABERINTO *laberinto): imprime el laberinto por pantalla.

3
BOOLEANO es_casilla_permitida(LABERINTO *laberinto, COORDENADA *posicion_actual): dice si
podemos ocupar esa casilla del laberinto o no; podemos ocupar las casillas que tienen un espacio
vaco, 'E' o 'S'.

BOOLEANO es_casilla_salida(LABERINTO *laberinto, COORDENADA *posicion_actual): dice si esa


casilla es la salida ( 'S') o no.

MOVIMIENTO politica_movimiento(MOVIMIENTO ultimo_movimiento): en base al ltimo movimiento que


se ha realizado, nos dice qu movimiento debemos de intentar ahora. Por ejemplo: ninguno-
>arriba, arriba->derecha, derecha->abajo, abajo->izquierda, izquierda->ninguno. Esta funcin
debe implementarse con un switch.

MOVIMIENTO movimiento_opuesto(MOVIMIENTO movimiento): para un movimiento dado, nos dice su


opuesto. Izquierda y derecha son opuestos, arriba y abajo son opuestos. El opuesto de ninguno es
ninguno. Esta funcin se debe implementar con un switch.

COORDENADA calcula_nueva_posicion(COORDENADA *posicion_actual, MOVIMIENTO


siguiente_movimiento): esta funcin nos dice que coordenada tendremos si realizamos el
movimiento especificado desde la posicion actual. Esta funcin se debe implementar con un switch.

void marca_laberinto(LABERINTO *laberinto, COORDENADA *posicion_actual): esta funcin marca el


laberinto, en la posicin en la que estemos, con un punto (' . ).

La implementacin de estas funciones deber realizarse en un archivo de nombre laberinto.c. A


continuacin debe programarse el algoritmo de resolucin de laberinto, siguiendo el pseudo-
cdigo que se describe a continuacin. Dicho pseudo-cdigo ha sido tambin escrito como
comentarios en el archivo P24_xxx.c, el cual debe tomarse como referencia para escribir el
cdigo correspondiente.

inicializar la pila de movimientos

ultimo_movimiento_explorado = NINGUNO

salida_imposible = NO

salida_encontrada = es_casilla_salida(laberinto, posicion_actual);

mientras que no se haya encontrado la salida ni salida_imposible sea SI,

marcar la posicin actual en el laberinto, hallar siguiente movimiento segn nuestra


poltica y meterlo en la variable siguiente_opcion_movimiento

si la variable siguiente_opcion_movimiento no es NINGUNO,

ultimo_movimiento_explorado = siguiente_opcion_movimiento

calcular nueva posicion y meterla en la variable siguiente_posicion

si la casilla correspondiente a la nueva posicion es una casilla permitida

4
{

meter el movimiento que hemos hecho en la pila

ultimo_movimiento_explorado = NINGUNO

posicion_actual = siguiente_posicion

} en caso contrario

sacar un dato de la pila de movimientos (este dato contiene el movimiento que


me ha llevado a la actual posicion) y meterlo en ultimo_movimiento_explorado

si no he podido sacar nada de la pila porque no haba nada

salida_imposible = SI

en caso contrario

calcular la nueva posicin deshaciendo el movimiento que me ha llevado


a la casilla actual (tendr que moverme en la direccin opuesta),
asignndoselo a la variable posicion_actual

chequear si nos encontramos en la casilla de salida, en ese caso hacer SI la variable


salida_encontrada

} (fin del mientras)

A modo de resumen, el programa realizado deber:


- Recibir el nombre del archivo con el laberinto desde la lnea de comandos,
comprobando por lo tanto que recibe los argumentos adecuados.
- Volcar los datos del laberinto a la matriz "laberinto" (funcin lee_laberinto).
- Comprobar la existencia del archivo, devolviendo error en caso contrario.
- Controlar otros errores como el intento de lectura de laberintos demasiado grandes,
laberintos en los que las lneas tienen diferente tamao, laberintos en los que no haya
salida, o no haya entrada, laberintos en los que haya ms de una entrada, etc.
- Realizar una bsqueda de un posible camino desde la entrada (E) a la salida (S) del
laberinto. Se debern controlar errores tales como la existencia de laberintos en los que
no hay ningn camino posible desde la entrada a la salida, etc.
- Dar como salida la secuencia de movimientos necesaria para salir desde la entrada (E) a
la salida (S) del laberinto.
- Una vez encontrada la salida, imprimir el laberinto mostrando el camino recorrido.

Вам также может понравиться