Práctica 7 Tipos Abstractos y Estructuras de Datos Introducción a la Computación 1er cuatrimestre 2012 Ejercicio 1. a) Definir el TAD Fecha con (al menos) las siguientes operaciones, e implementarlo en Python: CrearFecha(d, m, a) → Fecha FechaSiguiente(f ) → Fecha: Devuelve la fecha siguiente a la fecha dada. (Ej: al 31/12/1999 le sigue el 1/1/2000.) Menor(f1 , f2 ) → B: Devuelve T RUE si la fecha f1 es anterior que la fecha f2 , y FALSE en caso contrario. b) Usar el TAD Fecha para resolver los siguientes problemas: (i) contar la cantidad de días entre dos fechas dadas; (ii) contar la cantidad de días “29 de febrero” entre dos fechas dadas. Ejercicio 2. Sea Lista(Z) el TAD que define las siguientes operaciones: CrearLista() → Lista(Z): Crea una lista vacía. Agregar(x, L): Inserta x al final de L. BorrarTodos(x, L): Borra todas las apariciones de x en L. Reemplazar(x, y, L): Reemplaza en L todas las ocurrencias de x por y. Longitud(L) → Z: Devuelve la cantidad de elementos de la lista. I-ésimo(i, L) → Z: Devuelve el i-ésimo elemento de L. Precondición: 0 ≤ i < Longitud(L). EstáVacía(L) → B: Devuelve T RUE si la lista no contiene elementos y FALSE en caso contrario. donde L : Lista(Z) y i, x, y : Z. Sean Nodo y Lista las estructuras de representación utilizadas para implementar el TAD: Tipo Lista==hprimero:Ref(TNodo)i Tipo Nodo==hvalor:Z, siguiente:Ref(TNodo)i El invariante de representación de la estructura propuesta es que Lista.primero apunta al primer elemento de la lista y no hay ciclos entre los nodos. Es decir, no existen nodos n1 , n2 . . . , nm tales que n1 .siguiente = n2 . . . nm−1 .siguiente = nm y nm .siguiente = n1 . a) Dar un algoritmo en pseudocódigo para cada una de las operaciones definidas en el TAD Lista(Z) utilizando la representación propuesta. b) Dar un algoritmo recursivo que imprima la lista en orden inverso (suponer que se cuenta con una función print(x), con x : Z ). c) Calcular el orden de los algoritmos propuestos. 1 d) Implementar los algoritmos en Python. e) Modificar la estructura propuesta y los algoritmos para las operaciones Agregar y Longitud de modo de que ambas pertenezcan a O(1). ¿Qué cambios hay que hacer en el resto de los algoritmos del TAD? Ejercicio 3. Sea Pila(Z) el TAD que define las siguientes operaciones: CrearPila() → Pila(Z): Crea una pila vacía. EstáVacía(P ) → B: Devuelve T RUE si P no contiene elementos y FALSE en caso contrario. Apilar(x, P ): Apila x en el tope de P . Desapilar(P ): Desapila el tope de P . Precondición: ¬EstáVacía(P ). Tope(P ) → Z: Devuelve el elemento que está en el tope de P . Precondición: ¬EstáVacía(P ). donde P : Pila(Z) y x : Z. Sea la siguiente estructura de representación: Tipo Pila==helementos:Lista(Z)i donde Lista(Z) es el TAD del ejercicio 2. a) Dar el invariante de representación para la estructura propuesta. b) Escribir en pseudocódigo los algoritmos de las operaciones definidas en el TAD Pila(Z). c) Implementar en Python. Ejercicio 4. Escribir un algoritmo que determine si un string dado está balanceado con respecto a los caracteres { }, [ ], ( ). Ejemplos: “{a(b)x[()]}” está balanceado; “}”, “a(b))” y “[[})” no están balanceados. Sugerencia: Usar el TAD Pila(char). Ejercicio 5. Sea Cola(Z) el TAD que define las siguientes operaciones: CrearCola() → Cola(Z): Crea una cola vacía. EstáVacía(C) → B: Devuelve T RUE si C no contiene elementos y FALSE en caso contrario. Encolar(x, C): Encola x al final de la cola C. SacarPrimero(C) → Z: Saca de C el primer elemento y lo devuelve. Precondición: ¬EstáVacía(C). donde C : Cola(Z) y x : Z. Sea la siguiente estructura de representación: Tipo Cola==helementos:Lista(Z)i donde Lista(Z) es el TAD del ejercicio 2. a) Dar el invariante de representación para la estructura propuesta. b) Escribir en pseudocódigo los algoritmos de las operaciones definidas en el TAD Cola(Z). c) Implementar en Python. 2 Ejercicio 6. Sea Conjunto(Z) el TAD que define las siguientes operaciones: CrearConjunto() → Conjunto(Z): Crea un conjunto vacío. Agregar(x, C): Agrega x a C. Pertenece(x, C) → B: Devuelve T RUE si x pertenece a C y FALSE en caso contrario. Tamaño(C) → Z: Devuelve el cardinal del conjunto. EstáVacío(C) → B: Devuelve T RUE si C no contiene elementos y FALSE en caso contrario. ListarElementos(C) → Lista(Z): Devuelve una lista con todos los elementos del conjunto. Unión(C1 , C2 ) → Conjunto(Z): Devuelve C1 ∪ C2 . Intersección(C1 , C2 ) → Conjunto(Z): Devuelve C1 ∩ C2 . Diferencia(C1 , C2 ) → Conjunto(Z): Devuelve C1 \ C2 . donde C : Conjunto(Z) y x : Z. Sea la siguiente estructura de representación: Tipo Conjunto==helementos:Lista(Z)i donde Lista(Z) es el TAD del ejercicio 2. a) Dar el invariante de representación para la estructura propuesta. b) Escribir en pseudocódigo los algoritmos de las operaciones definidas en el TAD Conjunto(Z). Ejercicio 7. Una estructura de representación alternativa para implementar el TAD es usando un Árbol binario de búsqueda (ABB), y puede representarse usando los siguientes tipos: Tipo Conjunto==hraiz:Ref(NodoBinario)i Tipo NodoBinario== hvalor:Z, hijoIzquierdo:Ref(NodoBinario), hijoDerecho:Ref(NodoBinario)i El invariante de representación de la estructura propuesta es que Conjunto.primero apunta a la raiz del arbol, no hay ciclos entre los nodos y para todo nodo n1 , n2 sucede que si n2 es alcanzable desde n1 .hijoIzquierdo, entonces n1 .valor > n2 .valor; si n2 es alcanzable desde n1 .hijoDerecha, entonces n1 .valor < n2 .valor. Por ejemplo, el siguiente dibujo muestra un ABB válido: a) Escribir en pseudocódigo los algoritmos de las operaciones definidas en el TAD Conjunto(Z) usando la estructura de representación descripta. b) Suponiendo una distribución uniforme de los enteros que se agregan al conjunto, estimar el orden, en promedio, de las operaciones Agregar y Pertenece. 3 c) Escribir en pseudocódigo un algoritmo que imprima en orden ascendente los elementos del conjunto (suponer que cuenta con una función print(x), con x : Z ). ¿Qué cambio debería hacer para imprimirlos en order descendente? d) Implementar en Python el TAD Conjunto(Z) usando como estructura un ABB. Ejercicio 8. Se quiere implementar un TAD ConjuntoDePalabras que define las siguientes operaciones: CrearConjuntoDePalabras() → ConjuntoDePalabras: Crea un conjunto de palabras vacío. Agregar(p, C): Agrega p a C. Pertenece(p, C) → B: Devuelve T RUE si p pertenece a C y FALSE en caso contrario. donde C : ConjuntoDePalabras y p : String. a) Elegir una estructura tal que las operaciones Agregar y Pertenece tengan orden m, donde m es la longitud de la palabra que se agrega o se busca (y no la cantidad de palabras que contiene el conjunto). Sugerencia: definir un tipo N odoN ario, que tenga una lista de hijos de longitud arbitraria. b) Implementar el TAD en Python. Ejercicio 9. a) Definir el TAD Tatetí, que provea operaciones para crear un juego, determinar de quién es el turno, hacer una jugada (cruz o círculo), y determinar si el juego terminó, quién fue el ganador o si hubo empate. b) Implementar el TAD en Python. c) (Opcional) Escribir un programa en Python que (usando el TAD Tatetí) permita al usuario jugar interactivamente contra la computadora, mostrando por pantalla el tablero y preguntando la siguiente movida. Las jugadas de la computadora pueden realizarse al azar. 4