Parcial de Programación 2

Anuncio
Instituto de Computación. Facultad de Ingeniería. Universidad de la República
Parcial de Programación 2
9 de Mayo de 2009
Generalidades:
•
•
•
•
•
•
•
•
La prueba es individual y sin material
La duración es 3hs
Sólo se contestan dudas acerca de la letra de los ejercicios
Escriba las hojas de un sólo lado y con letra clara
Comience la solución de cada ejercicio en una nueva hoja
Numere cada hoja, indicando en la primera el total
Coloque su número de cédula y nombre en cada hoja
SI TODAS LAS RESTRICCIONES EXPLICITADAS DE UN EJERCICIO NO SON CUMPLIDAS POR LA SOLUCIÓN
PROPUESTA, EL EJERCICIO TENDRÁ PUNTAJE 0. TENER EN CUENTA LAS NOTAS AL PIE DE CADA EJERCICIO
Ejercicio 1 (8 puntos (a) + 12 puntos (b))
Considere la siguiente declaración, en Módula-2, del tipo LBin de las listas que toman valores en {0,1}, que
representan números en base 2:
Bin = [0..1];
LBin = POINTER TO NodoListaBin;
NodoListaBin = RECORD
digito : Bin;
sig : LBin
END;
Los números binarios en esta representación tienen los dígitos de menor a mayor orden, de izquierda a derecha. Es
decir, que al final de la lista se encuentra el dígito más significativo (el de mayor orden) y al principio el menos
significativo (el de menor orden). Ejemplos:
Lista de tipo LBin
[1]
[0,1]
[0,1,0,0,1]
Número que representa en base 2
1
10
10010
Número que representa en base 10
1
0+2*(1) = 2
0 + 2*(1 + 2*(0 + 2*(0 + 2*(1)))) = 18
Se pide implementar las siguientes operaciones iterativas, accediendo directamente a la representación.
a) BinADec, que dada una lista L de tipo LBin, no vacía, devuelve el valor que representa L en notación decimal, sin
modificar L.
PROCEDURE BinADec (L : LBin) : CARDINAL;
(* Precondición: lista no vacía *)
Tener en cuenta que si [x1,x2,…xn] es la representación de un número binario, donde x1 es el dígito de menor orden y xn
el de mayor orden, el número en notación decimal se puede calcular como:
Decimal([x1,x2,…xn]) = x1 + 2*Decimal([x2,…xn]) = ….
b) Suma1, que dada una lista L1 de tipo LBin, no vacía, deja en L2 el mismo número en base 2 al que se le ha sumado
una unidad (1).
PROCEDURE Suma1 (VAR L : LBin);
(* Precondición: lista no vacía *)
Ejemplos:
Entradas
L = [1]
L = [0,1]
L = [1,1]
L = [1,1,1,0,1,0,0,1]
Resultado de Suma1
L = [0,1]
L = [1,1]
L = [0,0,1]
L = [0,0,0,1,1,0,0,1]
NOTAS (para las partes a y b):
• Las operaciones no deberán recorrer más de una vez la lista parámetro.
• No pueden usarse funciones o procedimientos auxiliares.
• Las listas no deben usar celdas dummy (cabeceras).
Ejercicio 2 (12 puntos + 8 puntos)
Considere las siguientes declaraciones, en Módula-2, del tipo de los árboles binarios de búsqueda de enteros, de tipo
ABB, y del tipo de los árboles binarios de pares de números naturales, de tipo ABPar:
ABB = POINTER TO ABBNode;
ABPar = POINTER TO ABParNode;
ABBNode = RECORD
dato : INTEGER;
izq : ABB;
der : ABB;
END;
ABParNode = RECORD
CantIzq : CARDINAL;
CantDer : CARDINAL;
izq : ABPar;
der : ABPar;
END;
Se pide implementar las siguientes funciones recursivamente, accediendo directamente a la representación y sin usar
operaciones auxiliares propias:
a) Anotar, que dado un árbol A de tipo ABB, devuelve otro árbol estructuralmente igual a A que contiene en cada
nodo un par de naturales que indican cuántos nodos hay a su izquierda (CantIzq) y cuántos a su derecha (CantDer).
Ejemplo:
5
3,6
2
1
Anotar
9
3
6
7
10
8
2,0
0,1
15
cantIzq = 3
3,2
0,0
0,0
1,1
cantDer = 2
0,1
0,0
0,0
Si el árbol es vacío, la función debe retornar el árbol vacío.
PROCEDURE Anotar (A : ABB) : ABPar;
b) MaxDesBalanceo, que dado un árbol de tipo ABPar con anotaciones (obtenidas a partir de la ejecución de la
función Anotar sobre un árbol de tipo ABB) devuelve el desbalanceo máximo para todos los nodos del árbol. El
desbalanceo de un nodo n es la diferencia entre la cantidad de nodos en los subárboles izquierdo y derecho de n. En el
ejemplo de arriba, el máximo desbalanceo es de 3 y se da en la raíz del árbol.
PROCEDURE MaxDesBalanceo (AAnot : ABPar) : CARDINAL;
(* Precondición: el árbol no es vacío.*)
SOLUCIONES:
Ejercicio 1) Parte a)
PROCEDURE BinADec (L : LBin) : CARDINAL;
VAR result, exp: CARDINAL;
BEGIN
result := 0;
exp := 1;
(* Se recorren dígitos de menor a mayor orden *)
WHILE (L <> NIL) DO
IF (L^.digito <> 0) THEN
result := result + exp
END;
exp := exp * 2;
L := L^.sig;
END;
RETURN result;
END BinADec;
Ejercicio 1) Parte b)
PROCEDURE Suma1 (VAR L : LBin); (* L puede pasarse tanto por copia como por referencia *)
VAR nodo, Lrec : LBin;
BEGIN
Lrec := L;
WHILE (Lrec.sig <> NIL) AND (Lrec^.digito = 1) DO
Lrec^.digito := 0;
Lrec := Lrec^.sig;
END;
IF (Lrec.sig <> NIL) OR (Lrec^.digito = 0) THEN
Lrec^.digito := 1;
ELSE
Lrec^.digito := 0;
NEW(nodo);
nodo^.digito := 1;
nodo^.sig := NIL;
Lrec^.sig := nodo;
END;
END Suma1;
Ejercicio 2) Parte a)
PROCEDURE Anotar (A : ABB): ABPar;
VAR AAnot : ABPar;
BEGIN
IF (A = NIL)
RETURN NIL;
ELSE
NEW(AAnot);
AAnot^.izq := Anotar(A^.izq);
AAnot^.der := Anotar(A^.der);
IF (A^.izq <> NIL) THEN
AAnot^.CantIzq := (AAnot^.izq)^.CantIzq + (AAnot^.izq)^.CantDer + 1;
ELSE
AAnot^.CantIzq := 0;
END;
IF (A^.der <> NIL) THEN
AAnot^.CantDer := (AAnot^.der)^.CantIzq + (AAnot^.der)^.CantDer + 1;
ELSE
AAnot^.CantDer := 0;
END;
RETURN AAnot;
END;
END Anotar;
Ejercicio 2) Parte b)
PROCEDURE MaxDesBalanceo (AAnot : ABPar): CARDINAL;
VAR max, dif : INTEGER;
BEGIN
max := ABS(AAnot^.CantIzq - AAnot^.CantDer);
IF (AAnot^.izq <> NIL) THEN
dif := MaxDesBalanceo (AAnot^.izq);
IF (dif > max) THEN
max := dif;
END;
END;
IF (AAnot^.der <> NIL) THEN
dif := MaxDesBalanceo (AAnot^.der);
IF (dif > max) THEN
max := dif;
END;
END;
RETURN max;
END MaxDesBalanceo;
Descargar