lunes, 14 de abril de 2014

Práctica AnagramasSimple Java POO

Buenas gente, aquí os traigo otra práctica. prAnagramasSimple. Como siempre, aquí os dejo linkeados el pdf (es el mismo que el de la práctica de llaves) y un programa principal para probarlo.

A diferencia de la práctica de las llaves, ésta parte del pdf si me permite copiar por lo que aquí os dejo el enunciado ;)
1. Un anagrama de una palabra es otra palabra obtenida mediante una permutación de sus letras; por ejemplo, saco es un anagrama de cosa. La signatura de una palabra se define como la cadena resultante de ordenar alfabéticamente las letras de dicha palabra en minúsculas. Así, la signatura de saco y cOSa es acos. Teniendo en cuenta esto se deberá construir una clase Palabra con las siguientes características: · Las instancias de esta clase deben mantener información de una palabra: una cadena de caracteres que la representa y su correspondiente signatura. · El constructor de la clase recibirá como argumento la cadena de caracteres y deberá construir su signatura. · La clase contará con un método boolean esAnagrama(Palabra), que determinará si la palabra argumento es o no un anagrama de la receptora. · Redefine los métodos equals(Object), hashCode() y toString(), teniendo en cuenta que para que dos palabras sean iguales basta con que lo sean las cadenas de caracteres correspondientes, con independencia de su tipografía (no se distinguen mayúsculas de minúsculas). · Deberá existir un orden natural entre palabras basado en el orden lexicográfico de las cadenas correspondientes con independencia de su tipografía. · Debe existir un método String getPalabra() que devuelve la cadena que representa la palabra y otro String getSignatura() que devuelve la cadena que representa la signatura. 2. Crear la clase Anagrama que almacenará palabras a partir de cadenas de caracteres que le proporcionaremos. En la información almacenada, cada palabra estará asociada con el conjunto de otras palabras incluidas en esta clase con las que forma un anagrama (ver el listado más abajo). · Define un constructor para crear la clase que inicializará las estructuras necesarias para guardar la información. Las palabras deberán estar ordenadas según el orden natural (ver el listado más abajo). · Define el método void nuevaPalabra(String) que incluye una nueva palabra a partir de la cadena que se le proporciona. Si la palabra ya se encuentra en la estructura no hace nada. Si no estaba, deberá asociarse a cualquier palabra que forme anagrama con ella. Además, esas que forman anagrama también deberán estar asociadas con ésta. Por ejemplo, al introducir mora, se debe asociar con amor, roma y ramo y a su vez, estas tres se deben asociar con mora. · Define el método void mostrarEnConsola() que muestra la información contenida en el anagrama en la salida estándar. El listado que hay más abajo muestra cómo hacerlo. Si las palabras introducidas en un anagrama son olí, ramo, amor, cosa, caso, ostra, lío, roma, astro, mora, lió, saco, el método que muestra en consola deberá producir la siguiente salida (nótese que no se muestra la signatura de las palabras): amor ( mora ramo roma ) astro ( ostra ) caso ( cosa saco ) cosa ( caso saco ) lió ( ) lío ( olí ) mora ( amor ramo roma ) olí ( lío ) ostra ( astro ) ramo ( amor mora roma ) roma ( amor mora ramo ) saco ( caso cosa ) 3. Además del orden natural definido para las palabras, construye una clase SatPalabra que proporcione un orden alternativo para las palabras basado en la longitud de las cadenas y, en caso de igualdad, en el orden ascendente lexicográfico, con independencia de su tipografía. Incluir un nuevo constructor a la clase Anagrama que tome como argumento un objeto de SatPalabra y cree un anagrama que genere el listado con esta ordenación alternativa: lió ( ) lío ( olí ) olí ( lío ) amor ( mora ramo roma ) caso ( cosa saco ) cosa ( caso saco ) ramo ( amor mora roma ) roma ( amor mora ramo ) saco ( caso cosa ) astro ( ostra ) ostra ( astro ) Ejemplo del programa principal (las palabras se debe introducir como argumentos del programa): 
public class mainAnagramas {
 public static void main (String[] args) {
  System.out.println("Orden Natural");
  Anagrama an1 = new Anagrama();
  for (String arg: args) {
   an1.nuevaPalabra(arg);
  }
  an1.mostrarEnConsola();
  System.out.println();
  System.out.println("Orden Alternativo");
  Anagrama an2 = new Anagrama(new SatPalabra());
  for (String arg: args) {an2.nuevaPalabra(arg);
  }
  an2.mostrarEnConsola();
 }
}

La salida producida:
Orden natural:
amor ( mora ramo roma )
astro ( ostra )
caso ( cosa saco )
cosa ( caso saco )
lió ( )
lío ( olí )
mora ( amor ramo roma )
olí ( lío )
ostra ( astro )
ramo ( amor mora roma )
roma ( amor mora ramo )
saco ( caso cosa )

Orden alternativo:
lió ( )
lío ( olí )
olí ( lío )
amor ( mora ramo roma )
caso ( cosa saco )
cosa ( caso saco )
mora ( amor ramo roma )
ramo ( amor mora roma )
roma ( amor mora ramo )
saco ( caso cosa )
astro ( ostra )
ostra ( astro )
Y aquí tenéis las soluciones:


Class Anagrama:
import java.util.*;


public class Anagrama {
 private Map<Palabra, Set<Palabra>> anagramas;
 
 public Anagrama() {
  anagramas = new TreeMap<Palabra, Set<Palabra>>();
 }
 public Anagrama(Comparator<Palabra> cs) {
  anagramas = new TreeMap<Palabra, Set<Palabra>>(cs);
 }
 public void nuevaPalabra(String pal) {
  Palabra sPal = new Palabra(pal);
  if(!anagramas.containsKey(sPal)) {
   //Creo una nueva entrada en la aplicación
   //Creo el conjunto vacío
   Set<Palabra> conjunto = new TreeSet<Palabra>();
   anagramas.put(sPal, conjunto);
  
   for(Palabra p: anagramas.keySet()) {
    if(sPal.esAnagrama(p) && (!sPal.equals(p))) {
     Set<Palabra> con = anagramas.get(p);
     con.add(sPal);
     Set<Palabra> condof = anagramas.get(sPal);
     condof.add(p);
    
    }  
   }
  }
 }


 public void mostrarEnConsola() {
  for( Palabra p : anagramas.keySet()) {
   System.out.print(p + "\t (" );
   for (Palabra p2 : anagramas.get(p)) {
    if(!p.equals(p2)) System.out.print(p2 + " ");
   }
   System.out.println(")");
  }
 }
}


Class Palabra:
import java.util.Arrays;


public class Palabra implements Comparable<Palabra>{
 private String cadena;
 private String signatura;
 
 public Palabra(String p) {
  cadena = p.toLowerCase();
  char [] s = p.toCharArray();
  Arrays.sort(s);
  signatura = new String(s);
 }
 
 public boolean esAnagrama(Palabra p) {
  return signatura.equals(p.signatura);
 }
 
 public boolean equals(Object p) {
 // boolean iguales = true;
  return cadena.equalsIgnoreCase(((Palabra) p).getPalabra());
 }
 
 public int hashCode() {
  return cadena.hashCode();
 }

 public String toString() {
  String std = new String(cadena /*+ " y su anagrama correspondiente " + signatura*/);
  return std;  
 }

 @Override
 public int compareTo(Palabra s) {
  // TODO Auto-generated method stub
  return cadena.compareToIgnoreCase(s.cadena);
 }
 public String getPalabra() {
  return cadena;
 }
 public String getSignatura() {
  return signatura;
 }
}


Class SatPalabra:
import java.util.Comparator;


public class SatPalabra implements Comparator<Palabra>{
 public int compare(Palabra arg0, Palabra arg1) {
  int ns;
  int aux = arg0.getPalabra().length() - arg1.getPalabra().length();
  if(aux<0) ns = -1;
  else if (aux> 0) ns = 1;
  else ns = arg0.compareTo(arg1);
  return ns;
 }

}

Bueno, ésta puede ser más pesada por el hecho de enterarse primero de lo que es un anagrama y, bueno, que tampoco es mucha diversión :p pero ánimo, que ya vereis que conforme avanzais se vuelve todo más ameno ;)

Saludos

No hay comentarios:

Publicar un comentario