Universidad Rey Juan Carlos Curso 2011/2012 Ingeniería Técnica en Informática de Gestión Licenciado en Dirección y Administración de Empresa + Ingeniería Técnica en Informática de Gestión Estructura de Datos y de la Información SEGUNDO PARCIAL 04-05-2012 Normas: La duración de esta parte del examen es de 2 horas y 30 minutos. Todos los ejercicios se entregarán en hojas separadas, incluidos los que se dejen en blanco. En cada ejercicio se indica su puntuación total y, en su caso, el valor de los apartados que lo componen. No está permitido el uso de apuntes, libros ni teléfonos móviles. Ejercicio 1 (3.5 puntos) Se desea implementar en Ada 95 un paquete ArbolTernario, que contendrá la implementación de árboles ternarios definidos por el TAD TipoArbolTernario. Este tipo de árboles se caracteriza por tener un grado máximo de 3, estando los 3 hijos ordenados y denominándose HijoIzquierdo, HijoCentral e HijoDerecho, respectivamente (similar a los árboles binarios). Las operaciones del TAD TipoArbolTernario son similares a las del TAD TipoArbin y su uso también es similar. Se puede ver su especificación algabraica en la figura 1. Para la implementación, se hará uso, obligatoriamente, del paquete Arbol proporcionado en el anexo. Para ello, el paquete ArbolTernario representará internamente el árbol de grado 3 con un árbol n-ario definido con el paquete Arbol. Ha de tenerse en cuenta que el paquete ArbolTernario no es un paquete hijo del paquete Arbol. Una solución propuesta que no haga uso del paquete Arbol para representar la estructura interna del árbol ternario, será considerada como una solución incorrecta. Se pide: (a) (1.5 puntos) Implementar la interfaz del paquete ArbolTernario (fichero .ads), incluyendo su parte privada. Solución: −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− −− Modulo : A r b o l T e r n a r i o −− F i c h e r o : Programa ( ) I n t e r f a z TAD ( x ) Implement . TAD ( ) Otros ( ) −− Autor ( e s ) : E .D. I . −− Fecha : A b r i l 2012 −− −− D e s c r i p c i o n : I n t e r f a z de un TAD g e n é r i c o para r e p r e s e n t a r −− y manipular Á r b o l e s t e r n a r i o s de e l e m e n t o s PRIVADOS. −− Implementación h a c i e n d o uso de l o s á r b o l e s n−a r i o s ESPECIFICACIÓN ÁrbolesTernarios PARÁMETROS GENÉRICOS TIPOS TipoElemento FIN PARÁMETROS TIPOS TipoArbolTernario OPERACIONES (* constructoras generadoras *) CrearArbolTernarioVacio: -> TipoArbolTernario ConstruirArbolTernario: TipoElemento x TipoArbolTernario x TipoArbolTernario x TipoArbolTernario -> TipoArbolTernario (* observadoras *) PARCIAL Raiz: TipoArbolTernario -> TipoElemento PARCIAL HijoIzquierdo: TipoArbolTernario -> TipoArbolTernario PARCIAL HijoCentral: TipoArbolTernario -> TipoArbolTernario PARCIAL HijoDerecho: TipoArbolTernario -> TipoArbolTernario EsArbolTernarioVacio: TipoArbolTernario -> Booleano VARIABLES r: TipoElemento; i,c,d: TipoArbolTernario; ECUACIONES DE DEFINITUD DEF(Raiz(ConstruirArbolTernario(r,i,c,d))) DEF(HijoIzquierdo(ConstruirArbolTernario(r,i,c,d))) DEF(HijoCentral(ConstruirArbolTernario(r,i,c,d))) DEF(HijoDerecho(ConstruirArbolTernario(r,i,c,d))) ECUACIONES Raiz(ConstruirArbolTernario(r,i,c,d)) = r HijoIzquierdo(ConstruirArbolTernario(r,i,c,d)) = i HijoCentral(ConstruirArbolTernario(r,i,c,d)) = c HijoDerecho(ConstruirArbolTernario(r,i,c,d)) = d EsArbolTernarioVacio(CrearArbolTernarioVacio) = CIERTO EsArbolTernarioVacio(ConstruirArbolTernario(r,i,c,d)) = FALSO FIN ESPECIFICACION Figura 1: Especificación algrabraica del TAD TipoArbolTernario −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− WITH Arbol ; GENERIC −− e l e m e n t o s d e l á r b o l TYPE TipoElemento IS PRIVATE ; PACKAGE A r b o l T e r n a r i o IS −− d e f i n i c i ó n p r i v a d a y l i m i t a d a d e l t i p o de d a t o s TYPE T i p o A r b o l T e r n a r i o IS LIMITED PRIVATE ; −− e x c e p c i o n e s ArbolTernarioVacio : EXCEPTION ; −− e l á r b o l e s t á v a c í o MemoriaAgotada : EXCEPTION ; −− l a memoria dinámica e s t á a g o t a d a −− O p e r a c i o n e s C o n s t r u c t o r a s Generadoras PROCEDURE C r e a r A r b o l T e r n a r i o V a c i o ( a r b o l : IN OUT T i p o A r b o l T e r n a r i o ) ; PROCEDURE C o n s t r u i r A r b o l T e r n a r i o ( e : IN TipoElemento ; i : IN OUT T i p o A r b o l T e r n a r i o ; c : IN OUT T i p o A r b o l T e r n a r i o ; d : IN OUT T i p o A r b o l T e r n a r i o ; a r b o l : IN OUT T i p o A r b o l T e r n a r i o ) ; FUNCTION Raiz ( a r b o l : IN T i p o A r b o l T e r n a r i o ) RETURN TipoElemento ; FUNCTION H i j o I z q u i e r d o ( a r b o l : IN T i p o A r b o l T e r n a r i o ) RETURN T i p o A r b o l T e r n a r i o ; FUNCTION H i j o C e n t r a l ( a r b o l : IN T i p o A r b o l T e r n a r i o ) RETURN T i p o A r b o l T e r n a r i o ; FUNCTION H i j o D e r e c h o ( a r b o l : IN T i p o A r b o l T e r n a r i o ) RETURN T i p o A r b o l T e r n a r i o ; FUNCTION E s A r b o l T e r n a r i o V a c i o ( a r b o l : T i p o A r b o l T e r n a r i o ) RETURN Boolean ; −− Otras o p e r a c i o n e s ( n e c e s a r i a s d e b i d o a que e l t i p o de d a t o s −− s e implementa como LIMITED PRIVATE ) . PROCEDURE Co pia r ( d e s t i n o : IN OUT T i p o A r b o l T e r n a r i o ; origen : IN T i p o A r b o l T e r n a r i o ) ; FUNCTION I g u a l ( a r b o l 1 , a r b o l 2 : T i p o A r b o l T e r n a r i o ) RETURN Boolean ; PROCEDURE D e s t r u i r ( a r b o l : IN OUT T i p o A r b o l T e r n a r i o ) ; PRIVATE −− Implementacion d e l t i p o u t i l i z a n d o a r b o l e s n−a r i o s TYPE TipoNodo IS RECORD v a c i o : Boolean ; e l e m e n t o : TipoElemento ; END RECORD ; PACKAGE Arbol3 IS NEW Arbol ( TipoElemento => TipoNodo ) ; TYPE T i p o A r b o l T e r n a r i o IS RECORD a r b o l : Arbol3 . TipoArbol ; END RECORD ; END A r b o l T e r n a r i o ; Listado: arbolternario.ads (b) (2 puntos) Implementar el cuerpo (.adb) del paquete ArbilTernario (implementación de todos los métodos declarados en el .ads) Solución: −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− −− Modulo : A r b o l T e r n a r i o −− F i c h e r o : Programa ( ) I n t e r f a z TAD ( ) Implement . TAD ( x ) Otros ( ) −− Autor ( e s ) : E .D. I . −− Fecha : A b r i l 2012 −− −− D e s c r i p c i o n : I n t e r f a z de un TAD g e n é r i c o para r e p r e s e n t a r −− y manipular Á r b o l e s t e r n a r i o s de e l e m e n t o s PRIVADOS. −− Implementación h a c i e n d o uso de l o s á r b o l e s n−a r i o s −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− WITH Arbol ; PACKAGE BODY A r b o l T e r n a r i o IS −− O p e r a c i o n e s C o n s t r u c t o r a s Generadoras PROCEDURE C r e a r A r b o l T e r n a r i o V a c i o ( a r b o l : IN OUT T i p o A r b o l T e r n a r i o ) IS nodoVacio : TipoNodo ; BEGIN nodoVacio . v a c i o := True ; Arbol3 . C r e a r A r b o l V a c i o ( a r b o l . a r b o l ) ; Arbol3 . I n s e r t a r H o j a ( nodoVacio , a r b o l . a r b o l ) ; END C r e a r A r b o l T e r n a r i o V a c i o ; PROCEDURE C o n s t r u i r A r b o l T e r n a r i o ( e : IN TipoElemento ; i : IN OUT T i p o A r b o l T e r n a r i o ; c : IN OUT T i p o A r b o l T e r n a r i o ; d : IN OUT T i p o A r b o l T e r n a r i o ; a r b o l : IN OUT T i p o A r b o l T e r n a r i o ) IS nodo : TipoNodo ; BEGIN nodo . e l e m e n t o := e ; nodo . v a c i o := F a l s e ; BEGIN Arbol3 . C r e a r A r b o l V a c i o ( a r b o l . a r b o l ) ; Arbol3 . I n s e r t a r H o j a ( nodo , a r b o l . a r b o l ) ; Arbol3 . I n s e r t a r H i j o ( i . a r b o l , a r b o l . a r b o l ) ; Arbol3 . I n s e r t a r H i j o ( c . a r b o l , a r b o l . a r b o l ) ; Arbol3 . I n s e r t a r H i j o ( d . a r b o l , a r b o l . a r b o l ) ; EXCEPTION WHEN Arbol3 . MemoriaAgotada => RAISE MemoriaAgotada ; END ; END C o n s t r u i r A r b o l T e r n a r i o ; FUNCTION Raiz ( a r b o l : IN T i p o A r b o l T e r n a r i o ) RETURN TipoElemento IS BEGIN IF E s A r b o l T e r n a r i o V a c i o ( a r b o l ) THEN RAISE A r b o l T e r n a r i o V a c i o ; ELSE RETURN Arbol3 . Raiz ( a r b o l . a r b o l ) . e l e m e n t o ; END IF ; END Raiz ; FUNCTION H i j o I z q u i e r d o ( a r b o l : IN T i p o A r b o l T e r n a r i o ) RETURN T i p o A r b o l T e r n a r i o IS BEGIN RETURN T i p o A r b o l T e r n a r i o ’ ( a r b o l => Arbol3 . P r i m e r H i j o ( a r b o l . a r b o l ) ) ; END H i j o I z q u i e r d o ; FUNCTION H i j o C e n t r a l ( a r b o l : IN T i p o A r b o l T e r n a r i o ) RETURN T i p o A r b o l T e r n a r i o IS BEGIN RETURN T i p o A r b o l T e r n a r i o ’ ( a r b o l => Arbol3 . S i g u i e n t e H e r m a n o ( Arbol3 . P r i m e r H i j o ( a r b o l . a r b o l ) ) ) ; END H i j o C e n t r a l ; FUNCTION H i j o D e r e c h o ( a r b o l : IN T i p o A r b o l T e r n a r i o ) RETURN T i p o A r b o l T e r n a r i o IS BEGIN RETURN T i p o A r b o l T e r n a r i o ’ ( a r b o l => Arbol3 . U l t i m o H i j o ( a r b o l . a r b o l ) ) ; END H i j o D e r e c h o ; FUNCTION E s A r b o l T e r n a r i o V a c i o ( a r b o l : T i p o A r b o l T e r n a r i o ) RETURN Boolean IS BEGIN RETURN ( Arbol3 . EsArbolVacio ( a r b o l . a r b o l ) ) OR ELSE ( Arbol3 . Raiz ( a r b o l . a r b o l ) . v a c i o = True ) ; END E s A r b o l T e r n a r i o V a c i o ; −− Otras o p e r a c i o n e s ( n e c e s a r i a s d e b i d o a que e l t i p o de d a t o s −− s e implementa como LIMITED PRIVATE ) . PROCEDURE Co pia r ( d e s t i n o : IN OUT T i p o A r b o l T e r n a r i o ; origen : IN T i p o A r b o l T e r n a r i o ) IS BEGIN Arbol3 . C opi ar ( d e s t i n o . a r b o l , o r i g e n . a r b o l ) ; END Co pia r ; FUNCTION I g u a l ( a r b o l 1 , a r b o l 2 : T i p o A r b o l T e r n a r i o ) RETURN Boolean IS BEGIN RETURN Arbol3 . I g u a l ( a r b o l 1 . a r b o l , a r b o l 2 . a r b o l ) ; END I g u a l ; PROCEDURE D e s t r u i r ( a r b o l : IN OUT T i p o A r b o l T e r n a r i o ) IS BEGIN Arbol3 . D e s t r u i r ( a r b o l . a r b o l ) ; END D e s t r u i r ; END A r b o l T e r n a r i o ; Listado: arbolternario.adb Ejercicio 2 (2 puntos) Al igual que en los árboles binarios, en los árboles ternarios se puede realizar recorridos. Utilizando como referencia el TAD ArbolTernario planteado en el examen, se pide: (a) (0.5 puntos) ¿Es posible realizar un recorrido Inorden en los árboles ternarios? Justifique su respuesta. Solución: En recorrido Inorden es aplicable a los árboles binarios y a los árboles con un grado par. Dicho recorrido implica recorrer recursivamente los sub-árboles izquierdos, colocar la raíz y hacer el recorrido por los sub-árboles derechos. En el caso de un árbol ternario, no tendría sentido, ya que la raíz nunca estaría en una posición central del recorrido. (b) (1.5 puntos) Cree un paquete hijo ArbolesTernarios.Recorridos en el que se implemente el recorrido en pre-orden con la siguiente operación: PreOrden: TipoArbolTernario → TipoLista(TipoElemento) i. (0.5 puntos) Definición de la interfaz del paquete ArbolesTernarios.Recorridos (.ads) Solución: −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− −− Modulo : Funciones s o b r e á r b o l e s t e r n a r i o s −− F i c h e r o : Programa ( ) I n t e r f a z TAD ( ) Implement . TAD ( ) Otros (X) −− Autor ( e s ) : E .D. I . −− Fecha : A b r i l 2012 −− −− D e s c r i p c i o n : Paquete h i j o d e l p a q u e t e Arbin que d e f i n e subprogramas −− a u x i l i a r e s de manejo de á r b o l e s b i n a r i o s que r e q u i e r e n e l uso de −− l i s t a s −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− WITH L i s t a s ; GENERIC −− El parametro a c t u a l d e b e s e r una i n s t a n c i a d e l p a q u e t e L i s t a −− con e l mismo t i p o de e l e m e n t o que A r b o l T e r n a r i o WITH PACKAGE L i s t a _ E l e m e n t o s IS NEW L i s t a s ( TipoElemento ) ; PACKAGE A r b o l T e r n a r i o . R e c o r r i d o s IS PROCEDURE Pre orden ( a r b o l : IN T i p o A r b o l T e r n a r i o ; l i s t a : IN OUT L i s t a _ E l e m e n t o s . T i p o L i s t a ) ; END A r b o l T e r n a r i o . R e c o r r i d o s ; Listado: arbolternario-recorridos.ads ii. (1.0 puntos) Implementación del cuerpo del paquete ArbolesTernarios.Recorridos (.adb) Solución: −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− −− Modulo : Funciones s o b r e á r b o l e s t e r n a r i o s −− F i c h e r o : Programa ( ) I n t e r f a z TAD ( ) Implement . TAD ( ) Otros (X) −− Autor ( e s ) : E .D. I . −− Fecha : A b r i l 2012 −− −− D e s c r i p c i o n : Implementación de un Paquete h i j o d e l p a q u e t e −− A r b o l T e r n a r i o −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− WITH Ada . E x c e p t i o n s ; PACKAGE BODY A r b o l T e r n a r i o . R e c o r r i d o s IS MSG_AGOTADA : CONSTANT S t r i n g := "La␣ memoria ␣ d i n a m i c a ␣ e s t a ␣ a g o t a d a " ; PROCEDURE Pre orden ( a r b o l : IN T i p o A r b o l T e r n a r i o ; l i s t a : IN OUT L i s t a _ E l e m e n t o s . T i p o L i s t a ) IS preorden_hi , preorden_hc , preorden_hd , l_tmp : L i s t a _ E l e m e n t o s . T i p o L i s t a ; BEGIN IF E s A r b o l T e r n a r i o V a c i o ( a r b o l ) THEN Lista_Elementos . CrearVacia ( l i s t a ) ; ELSE Pre orden ( H i j o I z q u i e r d o ( a r b o l ) , p r e o r d e n _ h i ) ; Pre orden ( H i j o C e n t r a l ( a r b o l ) , preorden_hc ) ; Pre orden ( H i j o D e r e c h o ( a r b o l ) , preorden_hd ) ; L i s t a _ E l e m e n t o s . Concatenar ( preorden_hi , preorden_hc , l_tmp ) ; L i s t a _ E l e m e n t o s . Concatenar ( l_tmp , preorden_hd , l i s t a ) ; L i s t a _ E l e m e n t o s . C o n s t r u i r ( Raiz ( a r b o l ) , l i s t a ) ; −− Como ’ Concatenar ’ no r e u t i l i z a l a memoria de ’ preorden_hi ’ , −− ’ preorden_hc y ’ preorden_hd ’ , debemos l i b e r a r l a Lista_Elementos . D e s t r u i r ( preorden_hi ) ; L i s t a _ E l e m e n t o s . D e s t r u i r ( preorden_hc ) ; L i s t a _ E l e m e n t o s . D e s t r u i r ( preorden_hd ) ; END IF ; END Pre orden ; END A r b o l T e r n a r i o . R e c o r r i d o s ; Listado: arbolternario-recorridos.adb Ejercicio 3 (4.5 puntos) El problema de la generación de palabras consiste en hallar un algoritmo que permita generar palabras de una longitud menor o igual a una constante dada, pertenecientes a un lenguaje formal determinado. Considérese el lenguaje formal L = {an cbn cdn |n ≥ 0} definido sobre el alfabeto Σ = {a, b, c, d}. A este lenguaje pertenecen, entre otras, las palabras “cc”, “acbcd”, “aacbbcdd” y “aaacbbbcddd”. El número de símbolos de una palabra de este lenguaje (es decir, su longitud) es de la forma 3n + 2, con n ≥ 0. Teniendo en cuenta el esquema de diseño de algoritmos basado en espacios de estados, responda a las siguientes cuestiones: (a) (1 punto) Representar gráficamente el espacio de estados del problema de la generación de palabras de longitud máxima 5 aplicado al lenguaje L. Indíquense claramente las variables de estado de cada nodo del grafo (y sus valores) así como las componentes de la solución asociadas a los arcos. Solución: Además de la solución parcial, el estado almacena las siguientes variables: “ind”, contador de los símbolos ya introducidos (incrementado en una unidad) “aes”, contador del número de aes que todavía no tienen asociada una b “bes”, contador del número de bes que todavía no tienen asociada una d (b) (3 puntos) Implementar el tipo abstracto de datos TipoEstado mediante un paquete Ada 95 denominado Estados_Palabras. Se deberán implementar, únicamente, las siguientes operaciones: Inicializar, Avanzar, EsComponenteValida, ObtenerAlternativas y EsSolución. Supóngase que se encuentran disponibles los paquetes que implementan las componentes de la solución y las listas de dichos componentes. i. (1 punto) Implementar la especificación del paquete Estados_Palabras. Solución: WITH L i s t a s _ S i m b o l o s , S i m b o l o s ; PACKAGE E s t a d o s _ P a l a b r a s IS TYPE TipoEstado (N: P o s i t i v e ) IS LIMITED PRIVATE ; PROCEDURE I n i c i a l i z a r ( e s t a d o : OUT TipoEstado ) ; PROCEDURE Avanzar ( e s t a d o : IN TipoEstado ; componente : IN S i m b o l o s . Tipo_Simbolo ; s u c e s o r : OUT TipoEstado ) ; FUNCTION S o l u c i o n P a r c i a l ( e s t a d o : TipoEstado ) RETURN L i s t a s _ S i m b o l o s . T i p o L i s t a ; FUNCTION EsComponenteValida ( e s t a d o : TipoEstado ; componente : S i m b o l o s . Tipo_Simbolo ) RETURN Boolean ; PROCEDURE O b t e n e r A l t e r n a t i v a s ( e s t a d o : IN TipoEstado ; a l t e r n a t i v a s : OUT L i s t a s _ S i m b o l o s . T i p o L i s t a ) ; FUNCTION E s S o l u c i o n ( e s t a d o : TipoEstado ) RETURN Boolean ; PROCEDURE Co pia r ( d e s t i n o : IN OUT TipoEstado ; o r i g e n : IN TipoEstado ) ; FUNCTION "=" ( e s t a d o 1 , e s t a d o 2 : TipoEstado ) RETURN Boolean ; PROCEDURE D e s t r u i r ( e s t a d o : IN OUT TipoEstado ) ; PRIVATE TYPE TipoEstado (N: P o s i t i v e ) IS RECORD solucion_parcial : Listas_Simbolos . TipoLista ; numero_aes : N a t u r a l ; numero_bes : N a t u r a l ; indice : Positive ; END RECORD ; END E s t a d o s _ P a l a b r a s ; Listado: estados_palabras.ads ii. (2 puntos) Implementar el cuerpo del paquete Estados_Palabras (únicamente las operaciones Inicializar, Avanzar, EsComponenteValida, ObtenerAlternativas y EsSolución. Solución: WITH Ada . Text_IO ; WITH Listas_Simbolos_IO ; PACKAGE BODY E s t a d o s _ P a l a b r a s IS PROCEDURE I n i c i a l i z a r ( e s t a d o : OUT TipoEstado ) IS BEGIN Listas_Simbolos . CrearVacia ( estado . s o l u c i o n _ p a r c i a l ) ; e s t a d o . numero_aes := 0 ; e s t a d o . numero_bes := 0 ; e s t a d o . i n d i c e := 1 ; END I n i c i a l i z a r ; PROCEDURE Avanzar ( e s t a d o : IN TipoEstado ; componente : IN S i m b o l o s . Tipo_Simbolo ; s u c e s o r : OUT TipoEstado ) IS BEGIN Co pia r ( s u c e s o r , e s t a d o ) ; L i s t a s _ S i m b o l o s . I n s e r t a r F i n a l ( s u c e s o r . s o l u c i o n _ p a r c i a l , componente ) ; IF componente = ’ a ’ THEN s u c e s o r . numero_aes := s u c e s o r . numero_aes + 1 ; ELSIF componente = ’ b ’ THEN s u c e s o r . numero_bes := s u c e s o r . numero_bes + 1 ; s u c e s o r . numero_aes := s u c e s o r . numero_aes − 1 ; ELSIF componente = ’ d ’ THEN s u c e s o r . numero_bes := s u c e s o r . numero_bes − 1 ; END IF ; s u c e s o r . i n d i c e := s u c e s o r . i n d i c e + 1 ; END Avanzar ; FUNCTION S o l u c i o n P a r c i a l ( e s t a d o : TipoEstado ) RETURN L i s t a s _ S i m b o l o s . T i p o L i s t a IS BEGIN RETURN e s t a d o . s o l u c i o n _ p a r c i a l ; END S o l u c i o n P a r c i a l ; FUNCTION EsComponenteValida ( e s t a d o : TipoEstado ; componente : S i m b o l o s . Tipo_Simbolo ) RETURN Boolean IS BEGIN RETURN ( componente = ’ a ’ AND THEN e s t a d o . numero_aes < ( e s t a d o . N−2)/3 AND THEN ( e s t a d o . i n d i c e = 1 OR ELSE L i s t a s _ S i m b o l o s . Ultimo ( S o l u c i o n P a r c i a l ( e s t a d o ))= ’ a ’ ) ) OR ELSE ( componente = ’ b ’ AND THEN e s t a d o . numero_aes > 0 AND THEN ( L i s t a s _ S i m b o l o s . Ultimo ( S o l u c i o n P a r c i a l ( e s t a d o ))= ’ c ’ OR ELSE L i s t a s _ S i m b o l o s . Ultimo ( S o l u c i o n P a r c i a l ( e s t a d o ))= ’ b ’ ) ) OR ELSE ( componente = ’ c ’ AND THEN ( e s t a d o . numero_aes = 0 ) AND THEN ( e s t a d o . numero_bes = 0 ) AND THEN ( e s t a d o . i n d i c e = 1 OR ELSE L i s t a s _ S i m b o l o s . Ultimo ( S o l u c i o n P a r c i a l ( e s t a d o ))= ’ c ’ ) ) OR ELSE ( componente = ’ c ’ AND THEN ( e s t a d o . numero_aes > 0 ) AND THEN L i s t a s _ S i m b o l o s . Ultimo ( S o l u c i o n P a r c i a l ( e s t a d o ))= ’ a ’ ) OR ELSE ( componente = ’ c ’ AND THEN ( e s t a d o . numero_bes > 0 ) AND THEN ( e s t a d o . numero_aes = 0 ) AND THEN L i s t a s _ S i m b o l o s . Ultimo ( S o l u c i o n P a r c i a l ( e s t a d o ))= ’ b ’ ) OR ELSE ( componente = ’ d ’ AND THEN e s t a d o . numero_bes > 0 AND THEN ( L i s t a s _ S i m b o l o s . Ultimo ( S o l u c i o n P a r c i a l ( e s t a d o ))= ’ c ’ OR ELSE L i s t a s _ S i m b o l o s . Ultimo ( S o l u c i o n P a r c i a l ( e s t a d o ))= ’ d ’ ) ) ; END EsComponenteValida ; PROCEDURE O b t e n e r A l t e r n a t i v a s ( e s t a d o : IN TipoEstado ; a l t e r n a t i v a s : OUT L i s t a s _ S i m b o l o s . T i p o L i s t a ) IS BEGIN Listas_Simbolos . CrearVacia ( a l t e r n a t i v a s ) ; IF EsComponenteValida ( e s t a d o , ’ a ’ ) THEN Listas_Simbolos . Construir ( ’ a ’ , a l t e r n a t i v a s ) ; END IF ; IF EsComponenteValida ( e s t a d o , ’ b ’ ) THEN Listas_Simbolos . Construir ( ’b ’ , a l t e r n a t i v a s ) ; END IF ; IF EsComponenteValida ( e s t a d o , ’ c ’ ) THEN Listas_Simbolos . Construir ( ’ c ’ , a l t e r n a t i v a s ) ; END IF ; IF EsComponenteValida ( e s t a d o , ’ d ’ ) THEN Listas_Simbolos . Construir ( ’d ’ , a l t e r n a t i v a s ) ; END IF ; END O b t e n e r A l t e r n a t i v a s ; FUNCTION E s S o l u c i o n ( e s t a d o : TipoEstado ) RETURN Boolean IS BEGIN RETURN e s t a d o . i n d i c e > 2 AND THEN e s t a d o . numero_aes=0 AND THEN e s t a d o . numero_bes =0; END E s S o l u c i o n ; PROCEDURE Co pia r ( d e s t i n o : IN OUT TipoEstado ; o r i g e n : IN TipoEstado ) IS BEGIN d e s t i n o . i n d i c e := o r i g e n . i n d i c e ; d e s t i n o . numero_aes := o r i g e n . numero_aes ; d e s t i n o . numero_bes := o r i g e n . numero_bes ; L i s t a s _ S i m b o l o s . Co pi ar ( d e s t i n o . s o l u c i o n _ p a r c i a l , o r i g e n . s o l u c i o n _ p a r c i a l ) ; END Co pia r ; FUNCTION "=" ( e s t a d o 1 , e s t a d o 2 : TipoEstado ) RETURN Boolean IS BEGIN −− NO IMPLEMENTADO RETURN F a l s e ; END "=" ; PROCEDURE D e s t r u i r ( e s t a d o : IN OUT TipoEstado ) IS BEGIN Listas_Simbolos . Destruir ( estado . solucion_parcial ) ; END D e s t r u i r ; END E s t a d o s _ P a l a b r a s ; Listado: estados_palabras.adb (c) (0.5 puntos) Supóngase que deseamos encontrar la palabra más corta que pertenece a un lenguaje determinado. ¿Qué estrategia de búsqueda sería más adecuada: anchura o profundidad? Justifique brevemente la respuesta. Solución: La estrategia basada en anchura es la más adecuada, ya que ofrece una solución óptima en cuanto a la cantidad de componentes que forman parte de la solución: la primera solución encontrada sería la de menor número de componentes. ANEXO WITH Componentes , Listas_Componentes , . . . ; PACKAGE E s t a d o s IS TYPE TipoEstado IS LIMITED PRIVATE ; PROCEDURE I n i c i a l i z a r ( e s t a d o : OUT TipoEstado ; . . . ) ; PROCEDURE Avanzar ( e s t a d o : IN TipoEstado ; componente : IN Componentes . TipoComponente ; s u c e s o r : OUT TipoEstado ) ; FUNCTION S o l u c i o n P a r c i a l ( e s t a d o : TipoEstado ) RETURN Listas_Componentes . T i p o L i s t a ; FUNCTION EsComponenteValida ( e s t a d o : TipoEstado ; componente : Componentes . TipoComponente ) RETURN Boolean ; PROCEDURE O b t e n e r A l t e r n a t i v a s ( e s t a d o : IN TipoEstado ; a l t e r n a t i v a s : OUT Listas_Componentes . T i p o L i s t a ) ; FUNCTION E s S o l u c i o n ( e s t a d o : TipoEstado ) RETURN Boolean ; ... PRIVATE TYPE TipoEstado IS RECORD s o l u c i o n _ p a r c i a l : Listas_Componentes . T i p o L i s t a ; ... END RECORD ; END E s t a d o s ; Listado: Esquema estado para problemas de búsqueda GENERIC −− e l e m e n t o s d e l á r b o l TYPE TipoElemento IS PRIVATE ; PACKAGE a r b i n IS −− d e f i n i c i ó n p r i v a d a y l i m i t a d a d e l t i p o de d a t o s TYPE TipoArbin IS LIMITED PRIVATE ; −− e x c e p c i o n e s ArbolVacio MemoriaAgotada : EXCEPTION ; : EXCEPTION ; −− e l á r b o l e s t á v a c í o −− l a memoria dinámica e s t á a g o t a d a −− O p e r a c i o n e s C o n s t r u c t o r a s Generadoras PROCEDURE C r e a r A r b o l V a c i o ( a r b i n : IN OUT TipoArbin ) ; PROCEDURE C o n s t r u i r ( i z q d o : IN TipoArbin ; e : IN TipoElemento ; dcho : IN TipoArbin ; a r b i n : IN OUT TipoArbin ) ; −− O p e r a c i o n e s O b s e r v a d o r a s S e l e c t o r a s FUNCTION Raiz ( a r b i n : TipoArbin ) RETURN TipoElemento ; FUNCTION H i j o I z q d o ( a r b i n : TipoArbin ) RETURN TipoArbin ; FUNCTION HijoDcho ( a r b i n : TipoArbin ) RETURN TipoArbin ; −− Otras O p e r a c i o n e s O b s e r v a d o r a s FUNCTION EsArbolVacio ( a r b i n : TipoArbin ) RETURN Boolean ; −− Otras o p e r a c i o n e s ( n e c e s a r i a s d e b i d o a que e l t i p o de d a t o s −− s e implementa como LIMITED PRIVATE) . PROCEDURE Co pia r ( d e s t i n o : IN OUT TipoArbin ; origen : IN TipoArbin ) ; FUNCTION "=" ( a r b i n 1 , a r b i n 2 : TipoArbin ) RETURN Boolean ; PROCEDURE D e s t r u i r ( a r b i n : IN OUT TipoArbin ) ; −− Otras o p e r a c i o n e s PROCEDURE A l i a s ( d e s t i n o : IN OUT TipoArbin ; o r i g e n : IN TipoArbin ) ; PRIVATE ... END a r b i n ; Listado: Paquete Arbin −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− −− Modulo : A r b o l −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− GENERIC TYPE TipoElemento IS PRIVATE ; PACKAGE Arbol IS TYPE TipoArbol IS −− e x c e p c i o n e s ArbolVacio : MemoriaAgotada : HijoInexistente : LIMITED PRIVATE ; EXCEPTION ; EXCEPTION ; EXCEPTION ; −− e l á r b o l e s t á v a c í o −− l a memoria dinámica e s t á a g o t a d a −− no e x i s t e e l h i j o −− O p e r a c i o n e s C o n s t r u c t o r a s Generadoras PROCEDURE C r e a r A r b o l V a c i o ( a r b o l : IN OUT TipoArbol ) ; PROCEDURE I n s e r t a r H o j a ( e : IN TipoElemento ; a r b o l : IN OUT TipoArbol ) ; PROCEDURE I n s e r t a r H i j o ( h i j o : IN OUT TipoArbol ; a r b o l : IN OUT TipoArbol ) ; −− O p e r a c i o n e s o b s e r v a d o r a s FUNCTION Raiz ( a r b o l : TipoArbol ) RETURN TipoElemento ; FUNCTION P r i m e r H i j o ( a r b o l : TipoArbol ) RETURN TipoArbol ; FUNCTION S i g u i e n t e H e r m a n o ( a r b o l : TipoArbol ) RETURN TipoArbol ; FUNCTION O b t e n e r H i j o ( e : IN TipoElemento ; a r b o l : IN TipoArbol ) RETURN TipoArbol ; FUNCTION U l t i m o H i j o ( a r b o l : TipoArbol ) RETURN TipoArbol ; FUNCTION Padre ( a r b o l : TipoArbol ) RETURN TipoArbol ; FUNCTION HermanoAnterior ( a r b o l : TipoArbol ) RETURN TipoArbol ; FUNCTION EsArbolVacio ( a r b o l : TipoArbol ) RETURN Boolean ; FUNCTION EsHoja ( a r b o l : TipoArbol ) RETURN Boolean ; FUNCTION T i e n e S i g u i e n t e H e r m a n o ( a r b o l : TipoArbol ) RETURN Boolean ; FUNCTION TienePadre ( a r b o l : TipoArbol ) RETURN Boolean ; FUNCTION E s P r i m e r H i j o ( a r b o l : IN TipoArbol ) RETURN Boolean ; −− Otras o p e r a c i o n e s ( n e c e s a r i a s d e b i d o a que e l t i p o de d a t o s −− s e implementa como LIMITED PRIVATE ) . PROCEDURE Co pia r ( d e s t i n o : IN OUT TipoArbol ; origen : IN TipoArbol ) ; FUNCTION I g u a l ( a r b o l 1 , a r b o l 2 : TipoArbol ) RETURN Boolean ; PROCEDURE D e s t r u i r ( a r b o l : IN OUT TipoArbol ) ; −− Otras o p e r a c i o n e s PROCEDURE A l i a s ( d e s t i n o : IN OUT TipoArbol ; o r i g e n : IN TipoArbol ) ; PRIVATE ... END Arbol ; Listado: Árbol GENERIC TYPE TipoElemento IS PRIVATE ; PACKAGE L i s t a s IS TYPE T i p o L i s t a IS LIMITED PRIVATE ; TYPE TipoCursor IS PRIVATE ; −− e x c e p c i o n e s ListaVacia , MemoriaAgotada , CursorNoValido : EXCEPTION ; −−O p e r a c i o n e s C o n s t r u c t o r a s Generadoras PROCEDURE C r e a r V a c i a ( l i s t a : IN OUT T i p o L i s t a ) ; PROCEDURE C o n s t r u i r ( e : IN TipoElemento ; l i s t a : IN OUT T i p o L i s t a ) ; −− O p e r a c i o n e s O b s e r v a d o r a s FUNCTION FUNCTION FUNCTION FUNCTION FUNCTION Primero ( l i s t a : T i p o L i s t a ) RETURN TipoElemento ; EsVacia ( l i s t a : T i p o L i s t a ) RETURN Boolean ; Lo ng itu d ( l i s t a : T i p o L i s t a ) RETURN N a t u r a l ; Ultimo ( l i s t a : T i p o L i s t a ) RETURN TipoElemento ; P e r t e n e c e ( e : TipoElemento ; l i s t a : T i p o L i s t a ) RETURN Boolean ; −− O p e r a c i o n e s c o n s t r u c t o r a s no g e n e r a d o r a s PROCEDURE Resto ( l i s t a : IN T i p o L i s t a ; r e s t o : IN OUT T i p o L i s t a ) ; PROCEDURE I n s e r t a r F i n a l ( l i s t a : IN OUT T i p o L i s t a ; e : IN TipoElemento ) ; PROCEDURE Concatenar ( l 1 : IN T i p o L i s t a ; l 2 : IN T i p o L i s t a ; s a l i d a : IN OUT T i p o L i s t a ) ; PROCEDURE BorrarElemento ( e : IN TipoElemento ; l i s t a : IN OUT T i p o L i s t a ) ; −− Otras o p e r a c i o n e s PROCEDURE Co pia r ( d e s t i n o : IN OUT T i p o L i s t a ; origen : IN T i p o L i s t a ) ; FUNCTION "=" ( l i s t a 1 , l i s t a 2 : T i p o L i s t a ) RETURN Boolean ; PROCEDURE D e s t r u i r ( l i s t a : IN OUT T i p o L i s t a ) ; −− OPERACIONES RELACIONADAS CON EL MANEJO DE CURSORES −− O b s e r v a d o r a s FUNCTION Elemento ( l i s t a : T i p o L i s t a ; c : TipoCursor ) RETURN TipoElemento ; −− Otras c o n s t r u c t o r a s PROCEDURE I n s e r t a r ( l i s t a : IN OUT T i p o L i s t a ; c : IN TipoCursor ; e l e : IN TipoElemento ; d e t r a s : IN Boolean := True ) ; PROCEDURE Reemplazar ( l i s t a : IN OUT T i p o L i s t a ; c : IN TipoCursor ; e l e : IN TipoElemento ) ; PROCEDURE E l i m i n a r ( l i s t a : IN OUT T i p o L i s t a ; c : IN OUT TipoCursor ) ; −− Otras o p e r a c i o n e s A u x i l i a r e s FUNCTION FUNCTION FUNCTION FUNCTION FUNCTION FUNCTION FUNCTION P r i m e r C u r s o r ( l i s t a : T i p o L i s t a ) RETURN TipoCursor ; U lti m o C u rs o r ( l i s t a : T i p o L i s t a ) RETURN TipoCursor ; S i g u i e n t e ( l i s t a : T i p o L i s t a ; c : TipoCursor ) RETURN TipoCursor ; A n t e r i o r ( l i s t a : T i p o L i s t a ; c : TipoCursor ) RETURN TipoCursor ; E s C u r s o r V a l i d o ( l i s t a : T i p o L i s t a ; c : TipoCursor ) RETURN Boolean ; EsPrimero ( l i s t a : T i p o L i s t a ; c : TipoCursor ) RETURN Boolean ; EsUltimo ( l i s t a : T i p o L i s t a ; c : TipoCursor ) RETURN Boolean ; PRIVATE ... END L i s t a s ; Listado: Listas