DELTA – MASTER FORMACIÓN UNIVERSITARIA C/ Gral. Ampudia, 16 Teléf.: 91 533 38 42 - 91 535 19 32 28003 MADRID PROGRAMACION ORIENTADA A OBJETOS Ingenieria Informática Final Febrero 2006/07 Ejercicio 1. Un indice de referencias cruzadas de las palabras que aparecen en un texto es una tabla por palabras y, por cada una de ellas, los números de las líneas del texto donde aparecen, a los cuales se denomina referencias. Por ejemplo, considera un índice de referencias cruzadas como el siguiente: “casa”: 4,1,2,20,7 “árbol”: 1, 7,2,35,43,10 De este Ejemplo deducimos que el índice contiene, entre otras, la palabra “casa”, que aparece en las líneas 4,1,2, etc. Y que contiene asimismo la palabra “arbol”, que aparece en las líneas 1,7,2,etc. Las operaciones que admiten los índices de referencias cruzadas son los siguientes: • • • Obtener, en un arraylist, las referencias asociadas a una palabra Añadir una referencia de una palabra dada Obtener, en un set, las palabras contenidas en el índice Se pide: 1. [0.5] Definir la interfaz de los índices de referencias cruzadas. package Ejercicio1; import java.util.ArrayList; import java.util.Set; public interface ReferenciasCruzadas { public ArrayList<Integer> getReferencias(String nombre); public void anyadir(String nombre,int linea); public Set<String> listaPalabras(); } 1 DELTA – MASTER FORMACIÓN UNIVERSITARIA C/ Gral. Ampudia, 16 Teléf.: 91 533 38 42 - 91 535 19 32 28003 MADRID 2. [1] Implementar los índices de referencias cruzadas mediante un hashmap donde cada palabra tiene asociado un arraylist (no ordenado) con las referencias de dicha palabra. ackage Ejercicio1; import java.util.ArrayList; import java.util.HashMap; import java.util.Set; public class ReferenciasCruzadasImpl implements ReferenciasCruzadas { HashMap<String, ArrayList<Integer>> ref; public void anyadir(String nombre, int linea) { ArrayList<Integer> lista =ref.get(nombre); if (lista ==null) lista = new ArrayList<Integer>(new Integer(linea)); else lista.add(new Integer(linea)); ref.put(nombre,lista); } public ArrayList<Integer> getReferencias(String nombre) { return ref.get(nombre); } public Set<String> listaPalabras() { return ref.keySet(); } } 2 DELTA – MASTER FORMACIÓN UNIVERSITARIA C/ Gral. Ampudia, 16 Teléf.: 91 533 38 42 - 91 535 19 32 28003 MADRID 3. [1] Extender la clase anterior reescribiendo el método que añade una referencia, de forma que el arraylist de las referencias de una palabra siempre se encuentre ordenado. Se puede usar el método add(k,e) que permite insertar el objeto e en la posición k-esima de un arraylist. package Ejercicio1; import java.util.ArrayList; import java.util.Iterator; public class ReferenciasCruzadasExt extends ReferenciasCruzadasImpl { public void anyadir(String nombre, int linea) { ArrayList<Integer> lista =ref.get(nombre); if (lista ==null) lista = new ArrayList<Integer>(new Integer(linea)); else{ Iterator<Integer> it = lista.iterator(); int cont=0; while (it.hasNext()){ if (it.next().intValue()<linea) cont++; } lista.add(cont, new Integer(linea)); } ref.put(nombre,lista); } } 3 DELTA – MASTER FORMACIÓN UNIVERSITARIA C/ Gral. Ampudia, 16 Teléf.: 91 533 38 42 - 91 535 19 32 28003 MADRID 4. [1.5] Aplicar el patrón Memento a la clase del apartado 2. Al hacerlo debes definir en esa clase, un método estático clona(h) que devuelve un clon de un hashmap h que contenga un índice de referencias cruzadas. No se puede suponer dada la operación que clone arraylists. package Ejercicio1; import java.util.ArrayList; import java.util.HashMap; public class Memento { private HashMap<String, ArrayList<Integer>> state; public void setState( HashMap<String, ArrayList<Integer>> state ) { this.state = state; } public HashMap<String, ArrayList<Integer>> getState() { return state; } } package Ejercicio1; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.Set; public class ReferenciasCruzadasOriginator implements ReferenciasCruzadas { HashMap<String, ArrayList<Integer>> ref; HashMap<String, ArrayList<Integer>> state; public void anyadir(String nombre, int linea) { ArrayList<Integer> lista =ref.get(nombre); if (lista ==null) lista = new ArrayList<Integer>(new Integer(linea)); else lista.add(new Integer(linea)); ref.put(nombre,lista); } public ArrayList<Integer> getReferencias(String nombre) { return ref.get(nombre); } public Set<String> listaPalabras() { 4 DELTA – MASTER FORMACIÓN UNIVERSITARIA C/ Gral. Ampudia, 16 Teléf.: 91 533 38 42 - 91 535 19 32 28003 MADRID return ref.keySet(); } public Memento createMemento() { Memento memento = new Memento(); memento.setState( clona(ref)); return memento; } public void setMemento( Memento m ){ state = m.getState(); } public static HashMap<String, ArrayList<Integer>> clona(HashMap<String, ArrayList<Integer>> h){ HashMap<String, ArrayList<Integer>> sal = new HashMap<String, ArrayList<Integer>>(); Iterator<String> it = h.keySet().iterator(); while (it.hasNext()){ String nombre=it.next(); String nombreSal=new String(nombre); ArrayList<Integer> lista =h.get(nombre); Iterator<Integer> l= lista.iterator(); ArrayList<Integer> lsal = new ArrayList<Integer>(); while (l.hasNext()){ lsal.add(l.next()); } sal.put(nombreSal,lsal); } return sal; } } 5 DELTA – MASTER FORMACIÓN UNIVERSITARIA C/ Gral. Ampudia, 16 Teléf.: 91 533 38 42 - 91 535 19 32 28003 MADRID 5. [1] Aplicar el patrón Decorator a los índices de referencias cruzadas y, a partir del decorator, definir la clase de los índices de referencias cruzadas cuyas palabras tienen exactamente 4 letras. Para obtener el número de letras de una cadena de caracteres emplea el método length(). package Ejercicio1; import java.util.ArrayList; import java.util.Set; public abstract class Decorator extends ReferenciasCruzadasImpl { protected ReferenciasCruzadasImpl componente; public void setComponente(ReferenciasCruzadasImpl component) { this.componente = component; } public void anyadir(String nombre, int linea) { if (componente != null) componente.anyadir(nombre,linea); } public ArrayList<Integer> getReferencias(String nombre) { if (componente != null) return componente.getReferencias(nombre); return null; } public Set<String> listaPalabras() { if (componente != null) return componente.listaPalabras(); return null; } } package Ejercicio1; public class ReferenciasCruzadasDeCuatro extends Decorator { public void anyadir(String nombre, int linea) { if ((componente != null) && (nombre.length()==4)) componente.anyadir(nombre,linea); } } 6 DELTA – MASTER FORMACIÓN UNIVERSITARIA C/ Gral. Ampudia, 16 Teléf.: 91 533 38 42 - 91 535 19 32 28003 MADRID Ejercicio 2. Las colas son estructuras de datos que admiten las siguientes operaciones: • • • • Meter un elemento en la cola detrás del último Sacar de la cola el elmento que está primero, si lo hay Averiguar qué elemento es el primero de la cola, si lo hay Averiguar si la cola está vacia Se pide: 1.[0.5] Definir una interfaz genérica para representar las operaciones de las colas genéricas, así como la clase de excepciones que necesites. package Ejercicio2; public class ColaVaciaException extends Exception { private static final long serialVersionUID = 1L; } package Ejercicio2; public class ColaLlenaException extends Exception { private static final long serialVersionUID = 1L; } package Ejercicio2; public interface Cola<E> { public void insertar(E elto)throws ColaLlenaException; public E recuperaYBorra ()throws ColaVaciaException; public boolean esVacia(); public E recupera()throws ColaVaciaException; } 7 DELTA – MASTER FORMACIÓN UNIVERSITARIA C/ Gral. Ampudia, 16 Teléf.: 91 533 38 42 - 91 535 19 32 28003 MADRID 2 [1] Implementar las colas genéricas mediante un array y tres atributos que serven para conocer cuántos elementos tiene la cola, y dónde se encuentran el primero y el último elemento de la misma. El array además es circular en el sentido de que detrás de su última componente va la primera. Esto quiere decir que si, en un momento dado, en una cola que acaba en la última componente del array, se quiere meter un nuevo elemnto, éste de añadirá en la primera componente del array, si es que este componente está libre. Finalmente considera también que, en esta implementación, la operación que mete un elemnto en la cola, lanza y captura una excepción en caso de que el array esté lleno. package Ejercicio2; import java.util.ArrayList; public class ColaCircular<E> implements Cola<E> { private static final int tope = 100; int primero=0; int ultimo=0; ArrayList<E> datos=new ArrayList<E>(tope); public boolean esVacia() { return (primero==ultimo); } public void insertar(E elto) throws ColaLlenaException { if (((ultimo+1) % tope) == primero) throw new ColaLlenaException(); else{ datos.add(ultimo,elto); ultimo++; } } public E recupera() throws ColaVaciaException { if (esVacia()) throw new ColaVaciaException(); else return datos.get(primero); } public E recuperaYBorra() throws ColaVaciaException { E sal=null; if (esVacia()) throw new ColaVaciaException(); else { sal= datos.get(primero); primero++; } return sal; } } 8 DELTA – MASTER FORMACIÓN UNIVERSITARIA C/ Gral. Ampudia, 16 Teléf.: 91 533 38 42 - 91 535 19 32 28003 MADRID 3. [2] Implementar las colas genéricas mediante objetos con un solo atributo ult que es una lista genérica de tipo Lista<E>. Recuerda que los objetos de la clase Lista<E> tienen dos atributos: inf, de tipo genérica, y sig, del propio tipo Lista<E>. Se supone que la clase Lista<E> dispone de métodos públicos de acceso y mutación. La lista que representa la cola es una sucesión circular de nodos entrelazados por el atributo sig, de forma que el nodo siguiente al último de la cola es el nodo correspondiente al primero de la cola. Además el atributo ult apunta al nodo correspondiente al último elemento de la cola. package Ejercicio2; public class ColaCircularDinamica<E> implements Cola<E> { protected Lista<E> ult; public boolean esVacia() { return (ult==null); } public void insertar(E elto) throws ColaLlenaException { Lista<E> caja = new Lista<E>( elto,null); if (ult==null) caja.setSig(caja); else { caja.setSig(ult.getSig()); ult.setSig(caja); } ult=caja; } public E recupera() throws ColaVaciaException { if (ult==null) throw new ColaVaciaException(); else return ult.getSig().getInf(); } public E recuperaYBorra() throws ColaVaciaException { if (ult==null) throw new ColaVaciaException(); else { E salida = ult.getSig().getInf(); if (ult==ult.getSig()) ult =null; else ult.setSig(ult.getSig().getSig()); return salida; } } } 9 DELTA – MASTER FORMACIÓN UNIVERSITARIA C/ Gral. Ampudia, 16 Teléf.: 91 533 38 42 - 91 535 19 32 28003 MADRID 4 [1.5]. Define la clase de los iteradores para colas implementadas como en el apartado anterior. Para hacerlo puedes suponer que el atributo ult, mencionado antes es protegido. No es necesario definir el método remove(). No olvides la circularidad de la lista cuando la recorras public Iterator<E> iterator(){ return new IteradorColaCircilarDinamica (this); } package Ejercicio2; import java.util.Iterator; public class IteradorColaCircilarDinamica<E> implements Iterator<E> { private ColaCircularDinamica<E> data; private Lista<E> puntero; public IteradorColaCircilarDinamica( ColaCircularDinamica<E> colaCircularDinamica) { data=colaCircularDinamica; puntero = data.ult; } public boolean hasNext() { return (data.ult==null || (puntero.getSig()==data.ult)); } public E next() { E sal =puntero.getSig().getInf(); puntero=puntero.getSig(); return sal; } public void remove() { } } 10