Solución Examen Septiembre 2002

Anuncio
SOLUCIÓN EXAMEN DE ALGORITMOS Y ESTRUCTURAS DE DATOS II (AD2).
9 de Septiembre de 2002. Convocatoria Extraordinaria. Duración: 3 horas
Ejercicio 1 (prácticas). Puntuación: 2 puntos.
Los apellidos terminados en "EZ" provienen de los Visigodos, el pueblo germánico que, con la decadencia del Imperio
Romano, se estableció en la Península Ibérica y fundó aquí un Reino. "EZ" significa "Hijo de", y equivale a las
terminaciones "-son" de los apellidos de origen nórdico (Anderson, Johnson), "-vitch" o "-ievna" de los patronímicos rusos
(Nikolaievitch), etc... Así, el origen remoto de un "González" está en alguien que fue llamado ''Hijo de Gonzalo'' (González); "Álvarez" en ''Hijo de Álvaro'' (Álvar-ez); etc... De esta manera, toda una serie de apellidos hispánicos muy frecuentes
tiene su origen, en la Edad Media, en el nombre propio del padre [www.surnames.org/apellido.htm].
Se dispone de una función sufijoEz que comprueba si una palabra tiene “ez” como sufijo, cuya cabecera es la siguiente
function sufijoEz (var p: palabra): boolean;
Ejemplo: sufijoEz (‘González’) = true y sufijoEz (‘Marqués’) = false.
Una vez comprobado que una palabra tiene “ez” como sufijo, diseñar eficientemente en Pascal un procedimiento HijodeEz
que sustituye el sufijo ez por el sufijo o y añade como prefijo su traducción en castellano Hijode. Ejemplo: la palabra
González se cambiaría a HijodeGonzalo.
Utilícese la siguiente definición de tipos para completar en el recuadro el diseño en Pascal del procedimiento.
type
palabra = ^nodoPal;
nodoPal = record
letra: char;
sig: palabra
end;
{ sufijoEz(p) = true }
procedure HijodeEz (var p: palabra);
var ant_aux, aux, nuevo: palabra;
begin
ant_aux:= nil;
i:integer;
aux:= p;
(* Con este bucle ant_aux y aux apuntan al penúltimo y último nodo de la palabra, respectivamente. Es decir, al sufijo ‘ez’ *)
while (aux^.sig <> nil) do begin
ant_aux:= aux;
aux:= aux^.sig
end;
(* Se cambia la ‘e’ por la ‘o’ y se borra la ‘z’ *)
ant_aux^.letra := ‘o’;
ant_aux^.sig := nil;
dispose(aux);
(* Se crean y añaden en cabeza los nodos que forman el prefijo ‘Hijode’ *)
for i:= 1 to 6 do begin
new(nuevo);
case i of
1: nuevo^.letra:= ‘e’;
2: nuevo^.letra:= ‘d’;
3: nuevo^.letra:= ‘o’;
4: nuevo^.letra:= ‘j’;
5: nuevo^.letra:= ‘i’;
6: nuevo^.letra:= ‘H’
end;
nuevo^.sig := p;
p := nuevo
end;
end;
Ejercicio 2 (prácticas). Puntuación: 1.25 puntos.
La función recursiva campanadas averigua cuántas campanadas da un reloj de pared desde una hora especificada hasta el final
del día. Por ejemplo, si son las 20 horas, el reloj dará 50 campanadas ( 50 = 8 + 9 + 10 + 11 + 12 ).
const hfin = 24; hmitad = 12;
function campanadas (hora: integer): integer;
var ding_dong: integer;
begin
if (hora<=hfin) then begin
if (hora<=hmitad) then ding_dong := hora
else ding_dong := hora – hmitad;
campanadas := ding_dong + campanadas (hora+1)
end
else campanadas := 0
end;
Si la llamada inicial a la función campanadas desde el programa principal es nc := campanadas(h); siendo nc y h variables
globales de tipo integer e inicialmente h = 20, elegir de entre los tres registros de activación que se muestran en la figura, el
que se apila en primer lugar (en caso de respuesta incorrecta se resta 0.25) y rellenar parte de los registros de las
columnas de la pila. Cada columna representa la secuencia de registro(s) de activación cada vez que se detiene la ejecución
de la función debido a su punto de ruptura.
hora = 20
ding_dong = ?
campanadas = ?
24
?
?
hora
ding_dong
campanadas
20
?
23
?
?
23
11
?
22
?
22
10
22
10
21
?
?
21
9
?
21
9
?
21
9
?
20
8
20
8
20
8
20
8
Ejercicio 3 (prácticas). Puntuación: 0.75 puntos (en caso de respuesta incorrecta se resta 0.25).
En el siguiente fragmento de código, se ha medido el tiempo consumido por el procedimiento NumerosRomanos que
escribe la pronunciación en latín de los primeros num números. Ejemplo: NumerosRomanos(4), escribe utilizando
caracteres latinos la pronunciación de los números: 1 (unus), 2 (duo), 3 (tres) y 4 (quattuor).
…
var
n, t1, t2: integer;
…
procedure NumerosRomanos (num: integer);
var i: integer;
begin
i := 1;
while i≤num do begin
case i of
1: writeln(‘unus’);
2: writeln(‘duo’);
3: writeln(‘tres’);
4: writeln(‘quattuor’);
…
end;
i:=i+1
end
end;
begin {programa principal}
{línea 1} writeln (‘Talla Tiempo’);
{2}
n:=2;
{3}
while n<=100 do begin
{4}
t1:= clock;
{5}
NumerosRomanos (n*5);
{6}
t2:= clock-t1;
{7}
n := n + 2;
{8}
writeln (n*5:5, t2:7:2);
{9}
end;
end. {programa principal}
Los resultados obtenidos han sido:
Talla
10
20
.
.
500
Tiempo
0
0
.
.
0
Se quiere modificar adecuadamente el código anterior
para evaluar correctamente el tiempo consumido por el
procedimiento NumerosRomanos. Hay que modificar:
for k:=1 to rep do NumerosRomanos(n*5);
la línea 5:
writeln(n*5:5, t2/rep:7:2);
la línea 7:
con k variable entera y rep = número de repeticiones
necesarias para obtener tiempos significativos
n := n + 2
y la línea 8:
Ejercicio 4 (teoría). Puntuación: 1 punto.
Considérese el procedimiento NumerosRomanos del ejercicio anterior.
I) Puntuación: 0.25 puntos. Determinar la talla =
num
(valor del número)
II) Puntuación: 0.75 puntos (en caso de respuesta incorrecta se resta 0.25).
La complejidad temporal es: t(talla) ∈Θ(talla)
Ejercicio 5 (teoría). Puntuación: 1 punto.
Determinar la talla del algoritmo campanadas del ejercicio 2 y, en función de la misma, plantear las relaciones de
recurrencia correspondientes. Elegir de entre las complejidades indicadas la que corresponde a campanadas.
Talla: m = hfin – hora + 1
K1
si m = 0
(hora > 24)
K2 + t(m-1)
si m > 0
(hora ≤ 24)
Relaciones de recurrencia: t(m) =
Coste:
lineal
Ejercicio 6 (teoría). Puntuación: 1.5 puntos.
El siguiente procedimiento alachina, dada una palabra en español la traduce a espa-chino, es decir, pronunciada en
español a lo chino. Por ejemplo: las palabras “algoritmo” y “morro” serían en espa-chino “algolitmo” y “molo”,
respectivamente.
type
palabra = ^nodoPal;
nodoPal = record
letra: char;
sig: palabra
end;
{ p tiene al menos 1 símbolo }
procedure alachina (var p: palabra);
var aux, ant_aux: palabra;
begin
aux:= p^.sig; ant_aux:= p;
while (aux<>nil) do begin
if ant_aux^.letra = ‘r’ then begin
ant_aux^.letra:= ‘l’;
if aux^.letra = ‘r’ then begin
ant_aux^.sig := aux^.sig;
dispose(aux);
aux:=ant_aux^.sig
end;
end;
ant_aux := aux; aux:= aux^.sig
end;
if ant_aux^.letra = ‘r’ then ant_aux^.letra:= ‘l’;
end;
Estudiar el coste del procedimiento alachina en función de la talla del problema.
I) Puntuación: 0.75 puntos.
Talla = número de símbolos de la palabra p
II) Puntuación: 0.75 puntos (por cada respuesta incorrecta se resta 0.25).
no hay instancias significativas y el coste es: lineal con la talla del problema
Ejercicio 7 (teoría). Puntuación: 0.75 puntos (en caso de respuesta incorrecta se resta 0.25).
procedure alachina (p: palabra);
Si la cabecera del procedimiento anterior fuera
Tras la invocación, desde el algoritmo principal, al procedimiento alachina(pesp); siendo pesp una variable global de
tipo palabra:
pesp pasaría a ser la correspondiente palabra en espa-chino
Ejercicio 8 (teoría). Puntuación: 1.75 puntos (1.25 en caso de diseño iterativo).
Dada una lista (con punto de interés) l de palabras en español, diseñar un procedimiento palabraschinas que cambie las
palabras de la lista por su traducción a espa-chino, haciendo uso únicamente de:
a) las operaciones del TAD lista con punto de interés que se han estudiado en la teoría
procedimiento creal (ssal l: lista[palabra]);
procedimiento inserta (ent/sal l: lista[palabra]; ent p:palabra);
procedimiento suprime (ent/sal l:lista[palabra]);
función recupera (l: lista[palabra]) devuelve palabra;
b)
y del procedimiento alachina del ejercicio 6, cuya
procedimiento principio (ent/sal l: lista[palabra]);
procedimiento fin (ent/sal l: lista[palabra]);
procedimiento siguiente (ent/sal l: lista[palabra]);
función esvacial (l: lista[palabra]) devuelve lógico;
función esfinl (l: lista[palabra]) devuelve lógico;
cabecera es: procedimiento alachina (ent/sal p: palabra);
Por ejemplo:
La lista l = { “algoritmo”, “estructuras”, “dos”, “tres”, “cuatro”, “cinco”, “morro” } de palabras
en español es en espa-chino l = { “algolitmo”, “estluctulas”, “dos”, “tles”, “cuatlo”, “cinco”, “molo” }.
procedimiento palabraschinas (ent/sal l: lista[palabra]);
(* VERSIÓN ITERATIVA *)
var p: palabra; fvar;
principio(l);
mientras not esfinl(l) hacer
p := recupera(l);
alachina(p);
inserta(l, p);
suprime(l)
fmientras;
fprocedimiento;
(* VERSIÓN RECURSIVA *)
var p: palabra; fvar;
si not esfinl(l)
entonces p := recupera(l);
alachina(p);
inserta(l, p);
suprime(l);
palabraschinas(l)
fsi
fprocedimiento;
Llamada inicial para el procedimiento recursivo: principio( li );
palabraschinas( li );
siendo li una variable global declarada como sigue:
li: lista[palabra];
Descargar