--|:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: --| Solucion practica 5 de EDA del curso 98/99 (modulo de implementacion) --|:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: --| Version: 1.0 --| Fecha: 7-XII-98 --| Autor: Javier Campos with ada.strings.unbounded, ustrings, unchecked_deallocation; use ada.strings.unbounded, ustrings; package body dicc is -- type tipoNodo is (hoja,interior); -- type nodo; -- type ptNodo is access nodo; -- type nodo(tipo:tipoNodo) is record -- case tipo is -- when hoja => -- clave:ustring; -- info:ustring; -- when interior => -- pri,seg,ter:ptNodo; -- minseg,minter:ustring; -- end case; -- end record; -- type diccionario is record -- numpal:integer; -- nodos:ptNodo; -- end record; procedure disponer is new unchecked_deallocation(nodo,ptNodo); procedure vacio(d:out diccionario) is begin d.numpal:=0; d.nodos:=null; end vacio; procedure busca_rec(p:in ptNodo; palabra:in ustring; definicion:out ustring) is -- es la busqueda en el arbol (la pongo aqui porque se usa tambien en "=") begin if p.tipo=hoja then if palabra=p.clave then --palabra encontrada definicion:=p.info; else --palabra no encontrada definicion:=null_unbounded_string; end if; else --p.tipo=interior if palabra0 then --caso contrario el diccionario sigue vacio if d.numpal=1 then --el diccionario es una sola hoja if d.nodos.clave=palabra then --hay que borrarla disponer(d.nodos); d.nodos:=null; d.numpal:=0; end if; else --el diccionario tiene mas de un elemento borra_rec(d.nodos,palabra,unHijo,menor,hayBorrado); if hayBorrado then d.numpal:=d.numpal-1; end if; if unHijo then --la raiz solo tiene un hijo; hay que eliminar la raiz pAux:=d.nodos; d.nodos:=d.nodos.pri; disponer(pAux); end if; end if; end if; end borra; procedure asignar(dout:out diccionario; din:in diccionario) is procedure asignar_rec(pout:out ptNodo; pin:in ptNodo) is a1,a2,a3:ptNodo; begin if pin=null then --es vacio pout:=null; elsif pin.tipo=hoja then --un solo nodo pout:=new nodo'(hoja,pin.clave,pin.info); else --la raiz es un nodo interior asignar_rec(a1,pin.pri); asignar_rec(a2,pin.seg); if pin.ter/=null then asignar_rec(a3,pin.ter); end if; pout:=new nodo'(interior,a1,a2,a3,pin.minseg,pin.minter); end if; end asignar_rec; begin dout.numpal:=din.numpal; asignar_rec(dout.nodos,din.nodos); end asignar; function "="(d1,d2:in diccionario) return boolean is function incluido(p1,p2: ptNodo) return boolean is --devuelve verdad si y solo si todas las palabras de p1 estan en p2 (con iguales def.) def:ustring; aux:boolean; begin if p1=null then return true; --trivialmente elsif p1.tipo=hoja then busca_rec(p2,p1.clave,def); return def=p1.info; --solo hay una palabra en p1 y esta en p2 else --p1 es un nodo interior aux:=incluido(p1.pri,p2); if not aux then return false; else aux:=incluido(p1.seg,p2); if not aux then return false; elsif p1.ter/=null then aux:=incluido(p1.ter,p2); return aux; else return true; end if; end if; end if; end incluido; begin if d1.numpal/=d2.numpal then return false; else return incluido(d1.nodos,d2.nodos); end if; end "="; procedure liberar(d:in out diccionario) is procedure liberar_rec(p:in out ptNodo) is begin if p/=null then --hay algo que liberar if p.tipo=hoja then --solo una hoja disponer(p); p:=null; else --la raiz es un nodo interior liberar_rec(p.pri); liberar_rec(p.seg); liberar_rec(p.ter); disponer(p); p:=null; end if; end if; end liberar_rec; begin liberar_rec(d.nodos); d.numpal:=0; end liberar; procedure listado(d:in diccionario) is procedure listado_rec(p:in ptNodo) is begin if p/=null then --hay algo que listar if p.tipo=hoja then --un solo nodo put_line(p.clave); put_line(p.info); else listado_rec(p.pri); listado_rec(p.seg); listado_rec(p.ter); end if; end if; end listado_rec; begin listado_rec(d.nodos); end listado; end dicc;