Parcial de Programación 2

Anuncio
Instituto de Computación - Facultad de Ingeniería - Universidad de la República
Parcial de Programación 2
14 de Julio de 2014
Generalidades:
• La prueba es individual y sin material.
• Resuelva ejercicios diferentes en hojas diferentes.
• Duración: 3:30hs.
• Numere cada hoja, indicando en la primera el total.
• Sólo se contestan dudas acerca de la letra.
• Escriba su número de cédula y nombre en cada hoja.
• Escriba las hojas de un sólo lado y con letra clara.
• Escriba el código en Modula-2.
Ejercicio 1 (22 puntos)
Se desea modelar un TAD Urna que permita registrar votos a diferentes candidatos. Las operaciones con las
que debe contar el TAD son las siguientes:
•
UrnaVacia, que crea una Urna vacía.
•
InsertarVoto, que recibe un candidato y una Urna, y agrega a la Urna un voto para ese candidato.
•
CantVotos, que recibe un candidato y una Urna, y devuelve la cantidad de votos para ese candidato
que están en la Urna.
a) Escriba una especificación procedural del TAD Urna no acotado descripto anteriormente. Asuma
que los candidatos son de tipo String.
b) Desarrolle una implementación del TAD Urna especificado en la parte (a), de forma que
InsertarVoto sea O(1) en peor caso.
c) Indique para cada una de las tres operaciones implementadas en la parte (b) cuál es el orden de
tiempo de ejecución en el peor caso. Justifique brevemente.
d) Si sabe que hay n candidatos y que cada uno de ellos puede identificarse con un número en el rango
[1,n], explique qué implementación permitiría que las operaciones InsertarVoto y CantVotos sean
O(1) en peor caso. ¿Cuál sería el orden de tiempo de ejecución en ese caso de la operación
UrnaVacia?
Solución:
a)
DEFINITION MODULE Urna
TYPE Urna;
PROCEDURE UrnaVacia (VAR u: Urna);
(* Retorna la urna vacía en la variable u.
*)
PROCEDURE InsertarVoto (c: String; VAR u: Urna);
(* Agrega un voto al candidato c en la urna u.
*)
PROCEDURE CantVotos (c: String; u: Urna; VAR cant: CARDINAL);
(* Devuelve la cantidad de votos del candidato c en la variable *)
(* cant.
*)
END Urna;
1/6
Instituto de Computación - Facultad de Ingeniería - Universidad de la República
b)
TYPE
Urna =
NodoUrna =
POINTER TO NodoUrna;
RECORD
voto: String;
sig: Urna;
END;
PROCEDURE UrnaVacia (VAR u: Urna)
BEGIN
u := NIL
END VaciarUrna;
PROCEDURE InsertarVoto (c: String; VAR u: Urna)
VAR
auxUrna: Urna;
BEGIN
NEW(auxUrna);
auxUrna^.voto := c;
auxUrna^.sig := u;
u
:= auxUrna
END InsertarVoto;
PROCEDURE CantVotos (c: String; u: Urna; VAR cant: CARDINAL)
BEGIN
cant := 0;
WHILE (u <> NIL) DO
IF (u^.voto = c) THEN
cant := cant + 1
END;
u := u^.sig
END
END CantVotos;
2/6
Instituto de Computación - Facultad de Ingeniería - Universidad de la República
c)
•
•
•
UrnaVacia
La operación es de orden 1 ya que se trata de una asignación.
InsertarVoto
Tal cual se pide en la letra la operación es de orden 1. Esto se
debe a que se inserta un elemento al principio de una lista. Como
se tiene la referencia a esta posición por definición de la
estructura simplemente se debe crear el nuevo nodo y apuntar el
siguiente a la lista que ya se tenía.
CantVotos
Debido a que la urna es una lista de votos, es necesario recorrer
toda la lista para saber la cantidad de votos para cada candidato.
Por lo tanto el orden de esta operación es n.
d)
Aprovechando que se tiene el mapeo de los candidatos con un número en el
rango [1,n] se puede utilizar una implementación con un arreglo de
enteros como estructura de datos para representar la urna. El valor
almacenado en cada celda del arreglo sería la cantidad de votos del
candidato al que está asociado.
Como la búsqueda de los elementos en ese arreglo sería de orden 1 (la
celda i del arreglo representa al candidato i, para todo i perteneciente
al rango [1,n]), las operaciones InsertarVoto y CantVotos cumplirían con
la restricción.
La operación UrnaVacia deberá inicializar en 0 los valores de cada
candidato. Por lo tanto es necesario recorrer todo el arreglo, lo que
hace que esta operación sea de orden n.
Ejercicio 2 (10 puntos)
Dado el tipo Arbol23 para representar árboles 2-3 de naturales:
TYPE
Arbol23 = POINTER TO Nodo;
TipoNodo = (Nodo2,Nodo3);
Nodo
= RECORD
CASE tipo : TipoNodo OF
Nodo2 : val : CARDINAL; |
Nodo3 : valIzq, valDer : CARDINAL;
hijoMedio : Arbol23;
END;
hijoIzq, hijoDer : Arbol23;
END;
Accediendo a dicha representación, y aprovechando las propiedades de los árboles 2-3, implemente la
operación de búsqueda con O(log n) peor caso:
PROCEDURE Pertenece (elem: CARDINAL; arbol: Arbol23): BOOLEAN;
Solución:
•
•
•
Cada nodo tiene entre 2 y 3 hijos.
Todas las hojas están al mismo nivel.
Se cumple que si un nodo tiene n hijos, entonces el nodo tiene n-1
3/6
Instituto de Computación - Facultad de Ingeniería - Universidad de la República
•
claves.
La propiedad de orden es la siguiente:
◦ Si el nodo tiene 2 hojas, la rama izquierda contendrá valores
menores a la clave en la raíz y la derecha mayores.
◦ Si el nodo tiene 3 hojas, la rama izquierda contendrá valores
menores a las dos claves en la raíz, la rama del medio tiene
valores mayores a la clave izquierda y menores a la clave
derecha y la rama derecha tiene los valores mayores a las dos
claves.
Por lo tanto la búsqueda se puede implementar:
PROCEDURE Pertenece (elem: CARDINAL; arbol: Arbol23): BOOLEAN
BEGIN
IF (arbol = NIL) THEN
RETURN FALSE
ELSE
IF (arbol^.tipo = Nodo2) THEN
IF (arbol^.val = elem) THEN
RETURN TRUE
ELSE
IF (arbol^.val > elem) THEN
RETURN Pertenece(elem,arbol^.hijoIzq)
ELSE
RETURN Pertenece(elem,arbol^.hijoDer)
END
END
ELSE
IF ((arbol^.valIzq = elem) OR (arbol^.valDer = elem))
THEN
RETURN TRUE
ELSE
IF (arbol^.valIzq > elem) THEN
RETURN Pertenece(elem,arbol^.hijoIzq)
ELSIF (arbol^.valDer > elem) THEN
RETURN Pertenece(elem,arbol^.hijoMedio)
ELSE
RETURN Pertenece(elem,arbol^.hijoDer)
END
END
END
END
END Pertenece;
4/6
Instituto de Computación - Facultad de Ingeniería - Universidad de la República
Ejercicio 3 (28 puntos)
Suponga que se quiere determinar cuáles son las palabras que más aparecen en un texto. Dicho texto se
encuentra representado como una lista de pares (palabra, cantidad), donde palabra representa una palabra
del texto y cantidad es la cantidad de veces que dicha palabra aparece en el texto. Se cuenta con el tipo
Contador para representar los pares (palabra, cantidad), y con un TAD ListaContador con las operaciones
usuales del TAD Lista (recuerde que la inserción se hace al comienzo). Asuma la siguiente definición del
tipo Contador:
TYPE
Contador = RECORD
palabra :String; cantidad: CARDINAL; END;
Se quiere implementar una función ListarKMasFrecuentes, que dados un texto representado con el TAD
ListaContador y un entero k, devuelve una ListaContador con los k pares (palabra, cantidad) que
corresponden a las k palabras más frecuentes en el texto. Estos pares se devuelven ordenados en forma
decreciente según cantidad de apariciones. No hay un criterio de desempate preestablecido en caso de
empates en la cantidad de apariciones, quedando esto librado a la implementación. Si k es mayor que el largo
de la lista que representa el texto, se devuelven todas las palabras del texto. El encabezado de la función
ListarKMasFrecuentes es el siguiente:
PROCEDURE ListarMasFrecuentes (lst: ListaContador; k: CARDINAL): ListaContador;
A continuación se presentan ejemplos:
lst =[(quiero,3),(doy,2),(tengo,3),(yo,5),(necesito,3)]
ListarKMasFrecuentes(lst,0)= []
ListarKMasFrecuentes(lst,1)= [(yo,5)]
ListarKMasFrecuentes(lst,2)= [(yo,5),(quiero,3)] o
[(yo,5),(tengo,3)] o
[(yo,5),(necesito,3)]
a) Especifique el TAD Cola de Prioridad acotada de elementos del tipo Contador, donde un elemento
tiene más prioridad que otro si el valor de su campo cantidad es menor. El tamaño de la Cola de
Prioridad se define al momento de crearla. Incluya pre y post condiciones.
b) Implemente ListarKMasFrecuentes usando una Cola de Prioridad auxiliar de tamaño k con las
operaciones especificadas en (a) y las del TAD ListaContador. La lista original lst se puede
recorrer una sola vez.
c) Suponiendo que k es acotado por una constante MAX_K ¿cuál de las implementaciones, vistas en el
curso, para el TAD de la parte (a) es la más eficiente en tiempo de ejecución? Describa propiedades
y tiempos de ejecución en el peor caso para cada una de las operaciones especificadas.
Solución:
a)
PROCEDURE NuevaCPrio (tamaño: CARDINAL): ColaPrioridad;
(* Devuelve una ColaPrioridad vacía de tamaño 'tamaño'. *)
PROCEDURE InsertarCPrio (cont: Contador; VAR cp: ColaPrioridad);
(* Precondicion: 'cp' no está llena.
Inserta 'cont' en 'cp' con prioridad 'cont.cantidad'. *)
(************ Selectoras ****************)
PROCEDURE MinimoCPrio (cp: ColaPrioridad): Contador;
(* Precondición: 'cp' no está vacía.
Devuelve el Contador de 'cp' que tiene asociado el menor valor
5/6
Instituto de Computación - Facultad de Ingeniería - Universidad de la República
de cantidad, o sea, el de mayor prioridad. *)
(************ Predicados *************)
PROCEDURE EsVaciaCPrio (cp: ColaPrioridad): BOOLEAN;
(* Devuelve TRUE si 'cp' no tiene elementos, FALSE en otro caso. *)
PROCEDURE EsLlenaCPrio (cp: ColaPrioridad): BOOLEAN;
(* Devuelve TRUE si 'cp' tiene 'tamaño' elementos, FALSE en otro caso,
siendo 'tamaño' el parámetro pasado en la creación de 'cp'. *)
(************ Destructoras *************)
PROCEDURE EliminarMinCPrio (VAR cp: ColaPrioridad);
(* Precondición: 'cp' no está vacía.
Elimina de 'cp' el Contador que tiene asociado el menor valor
de cantidad. *)
b)PROCEDURE ListaKMasFrecuentes (lst: ListaContador, k:CARDINAL): ListaContador
VAR
cp:ColaPrioridad;
elem, elemMinimo:Contador;
lResultado:listaContador;
BEGIN
cp := NuevaCPrio (k);
WHILE (NOT EsVacia(lst)) DO
elem := Cabeza(lst);
lst := Cola(lst);
IF (NOT EsLlenaCPrio(cp)) THEN
InsertarCPrio (elem, cp)
ELSE
elemMinimo := MinimoCPrio(cp);
IF (elem.cantidad > elemMinimo.cantidad) THEN
EliminarMinCPrio(cp);
InsertarCPrio(elem,cp)
END
END
END;
lResultado:=Vacia();
WHILE (NOT EsVaciaCPrio(cp)) DO
Cons(MinimoCPrio(cp),lResultado);
EliminarMinCPrio(cp)
END;
RETURN lResultado
END ListaKMasFrecuentes;
c) Dado que k es acotado y que no hay obligaciones con respecto a la
forma de decidir el mínimo cuando hay empates, resulta que la más
eficiente en tiempos de ejecución de la implementaciones vistas en el
curso es la de heap implementado con un arreglo. Se detallan a
continuación los tiempos de ejecución de cada una de sus operaciones:
InsertarCPrio (cont: Contador; VAR cp: ColaPrioridad) - log(n)
MinimoCPrio (cp: ColaPrioridad): CONTADOR - O(1)
EsVaciaCPrio (cp: ColaPrioridad): BOOLEAN - O(1)
EsLlenaCPrio (cp: ColaPrioridad): BOOLEAN – O(1)
EliminarMinCPrio (VAR cp: ColaPrioridad) - log(n)
6/6
Descargar