La clase Sorter se usa de la siguiente manera. Suponga que Ud. ha construido su arreglo mediante la declaración:
Para ordenar arreglo se crea un objeto de la clase Sorter pasando
como argumento el arreglo:
double[] array= { 5.0, 10.0, -4.0, 15.0, 13.0, 46.0, -2.0};
El objeto construido es un ordenador de arreglos de números reales.
En este punto, el objeto sorter y la variable array referencian el
mismo arreglo. La construcción de sorter no ordena todavía el arreglo.
De hecho, el objeto posee métodos para desplegar el contenido del arreglo
en pantalla:
Sorter sorter= new Sorter(array);
El resultado de esta invocación será:
sorter.print();
5.0 10.0 -4.0 15.0 13.0 46.0 -2.0
Después de esta llamada el arreglo referenciado por array se encuentra
ordenado. Si ahora se invoca sorter.print(), el resultado
estará ordenado:
sorter.sort();
-4.0 -2.0 5.0 10.0 13.0 15.0 46.0
El resultado de este programa debe ser:
String[] array= {"pedro", "juan", "y", "diego"};
StringSorter sorter= new StringSorter(array);
sorter.sort();
sorter.print();
diego juan pedro y
Cambie el tipo del arreglo double[] por String[].
Cambie el nombre del constructor Sorter por StringSorter. El argumento debe ser de tipo String[].
El tipo de la variable x ya no es double. Debe ser String.
Compare el i-ésimo elemento con el j-ésimo invocando el método compareTo de la clase String.
No cambie los métodos sort, quicksort o particionar. El diseño de la clase coloca la parte compleja del problema en estos métodos. Estos métodos se abstraen del tipo de los elementos ordenados. Solo los métodos swap y compare toman en cuenta el tipo de los elementos del arreglo.
java PruStringSorter
Variante:
Modifique el programa de modo que ahora ordene descendentemente. En este caso Ud. sólo debe preocuparse de modificar el método compare.
Pregunta filosófica: ¿Cómo se podría escribir una clase que sirva tanto para ordenar arreglos de números reales como arreglos de strings?
Solución: usando subclases. Estudie cuidadosamente el capítulo de subclases y luego realice los ejercicios que se proponen a continuación.
Uno de los problemas de los lenguajes tradicionales como Pascal o C es que se necesita un programa de ordenamiento para cada tipo de datos. En Java y otros lenguajes orientados a objetos es posible hacer un ordenador genérico, es decir que ordene cualquier tipo de datos.
Para lograr esto, se ha encapsulado la parte esencial del algoritmo de ordenamiento en una clase llamada GenSorter. Esta clase ordena los elementos de un arreglo sin considerar el tipo específico de sus elementos. El algortimo trabaja comparando e intercambiando los elementos del arreglo. Estas operaciones se realizan por medio de la invocación de métodos abstractos que deben ser definidos en una subclase de GenSorter.
Para utilizar esta clase, se hace necesario entonces definir una subclase de GenSorter en donde ser definen los métodos que faltan y que dependen del tipo específico de los elementos del arreglo. Estos métodos son compare, swap y size.
La clase GenSorter es una clase abstracta. Esto significa que contiene métodos sin implementar. No se pueden crear instancias de una clase abstracta (con new). Una clase abstracta existe sólo con el fin de definir subclases de ella en donde se implementen (mediante redefinición) los métodos que aparecen sin implementación en la clase abstracta.
Examine ambos programas. Observe que en la clase IntSorter no se define el método sort y sin embargo se invoca. Esto es porque este método fue heredado de la clase GenSorter.
Para completar esta parte del ejercicio, Ud. sólo debe implementar un constructor para IntSorterDesc y redefinir el método compare. El resto de los métodos se heredan de IntSorterDesc.
Para completar esta parte del ejercicio, Ud. debe declarar una variable de instancia para referenciar el arreglo que se ordenará, implementar un constructor para StringSorter y redefinir los métodos compare, swap, size y print.
Este es un patrón de diseño muy útil que se puede usar para implementar algoritmos y/o estructuras de datos que dependen de un conjunto pequeño de operaciones. La idea consiste en resolver distintas variantes del mismo problema, sin tener que reescribir todo el código nuevamente. El algoritmo general se escribe en una clase abstracta y las operaciones dependientes de los tipos de datos manejados se especifican en subclases.