Está en la página 1de 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 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:
reserva memoria para la tabla o array de datos de la pila, devuelve error si no ha conseguido alocar memoria.
ESTADO InicializaPila(PILA *pila): BOOLEANO PilaVacia(PILA *pila): BOOLEANO PilaLlena(PILA *pila):

indica si la pila est o no vaca. indica si la pila est o no llena. introduce un elemento en la pila, devuelve error si

ESTADO Poner(PILA *pila, TIPO_INFO_PILA dato):

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 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.

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_permitida(LABERINTO *laberinto, COORDENADA *posicion_actual): BOOLEANO es_casilla_salida(LABERINTO *laberinto, COORDENADA *posicion_actual):

dice si esa

casilla es la salida ( 'S') o no. 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 politica_movimiento(MOVIMIENTO ultimo_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.
MOVIMIENTO movimiento_opuesto(MOVIMIENTO movimiento): COORDENADA calcula_nueva_posicion(COORDENADA *posicion_actual, 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.
siguiente_movimiento): 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 pseudocdigo 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

{ 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.

También podría gustarte