0 votos
Todo esto era unicamente un apartado de un trabajo final de asignatura (programacion l) para ser concretos.

En la practica, me implementan unas condiciones que son las siguientes:

DETALLES DE IMPLEMENTACIÓN:
El fichero de texto, puede contener espacios en blanco, saltos de línea, caracteres del alfabeto
(minúsculas sin acentos, ni diéresis) y los siguientes signos . , : @ ? ! " ( ) < >
Podemos considerar que un fichero tendrá como mucho n palabras diferentes, p.e. n = 500, en
caso de que se supere el límite debe avisar al usuario y no tratar el fichero.
No se puede usar la clase String para leer palabras o solventar algoritmos, si para leer
comandos o el ficheros a abrir.
Cualquier carácter que no esté en la tabla no debe encriptarse/desencriptarse.
Entrada de texto validada

 

Tuve que eliminar el uso de un import (StreamTokenizer) ya que un compañero me dijo que no podía utilizarlo para realizar lecturas de otros apartados( contar carácteres, palabras y lineas).

Me limitan esas condiciones a no poder usar el HashMap, ya que es algo que no hemos desarrollado a lo largo de la asignatura?

De ser así agradecería un impulso en cuanto a realizarlo por el uso de arrays y arrayLists, que si hemos "desarrollado" en esta asignatura.

 

Un saludo y muchas gracias!
preguntado por Noyalkrad Ene 25, 2015 en Java

1 Respuesta

+1 voto
Mejor respuesta
Si no te piden HashMap mejor no lo uses. Como veo que conoces todos los símbolos que te pueden entrar, un Array sería lo más rápido.

Puedes hacer algo parecido a lo que te comenté con HashMap pero con ArrayList. Es teniendo dos ArrayList, uno que guarde los caracteres y otro que guarde los contadores de cada uno. De este modo estarían emparejados, por ejemplo, la posición 3 del ArrayList de carácteres coincidiría con la posición 3 del ArrayList del contador. Es muy sencillo, para obtener establecer por posición puedes utilizar get() y set() http://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html#get(int)

Un poco más complicado, pero muy versátil es hacer un solo ArrayList con objetos, y cada objeto que contenga un String para los caracteres y un entero para los contadores. Tienes un ejemplo parecido en http://jarroba.com/ordenar-un-arraylist-en-java/, donde la clase "Persona" se comportaría como el objeto que te comento; evidentemente no necesitarías ordenar, pero si te lo pidieran, ahí tienes como se hace :)

Ya te he puesto algunas maneras. Realmente es lo que te resulte más cómodo Array o ArrayList. Te toca elegir.

El resto del ejercicio es lógica de comparativa básica, debería de salir solo :D
respondido por Ramon [Admin] Ene 25, 2015
seleccionada por Noyalkrad Ene 25, 2015
public void charRepe() {

        try {
            if (archivo.exists()) {
                System.out.println("Voy a definir los arrays");
                //Definición de variables y arrays a utilizar.
                int idx, carac;
                char lectcar;
                char[] caracteres = "abcdefghijklmnopqrstuvwxyz.,:@?!()<>".toCharArray();
                char[] abecedario = "abcdefghijklmnopqrstuvwxyz".toCharArray();
                int[] nVeces = new int[abecedario.length];
                //Creamos el buffer de lectura.
                System.out.println("He definido arrays");
                fr = new FileReader(fichero);
                BufferedReader read = new BufferedReader(fr);

                carac = read.read();
                lectcar = (char) carac;
                while (carac != -1) {
                    idx = 0;
                    while ((idx < caracteres.length - 1) && (lectcar != caracteres[idx])) {
                        idx++;
                    }
                    if (lectcar == caracteres[idx]) {
                        nVeces[idx]++;
                    }
                    //Pasamos al siguiente caracter.
                    carac = read.read();
                    //Y lo volvemos a introducir en la variable char de la lectura, (leemos en ints).
                    lectcar = (char) carac;
                }
                System.out.println();
                System.out.println("He llegado al for de impresiones.");
                for (int idxx = 0; idxx < nVeces.length; idxx++) {
                    if (nVeces[idxx] > 0) {
                        System.out.println("Número de apariciones de " + caracteres[idxx] + " es " + nVeces[idxx]);
                    }
                }
            }
        } catch (Exception e) {
            System.out.println("Error char repetido.");
        }
    }

A ver si podrías ayudarme de alguna forma, el método en si funciona a la perfección si cambio el array caracteres por el array abecedario, me cuenta todas las letras de manera correcta. Pero a la hora de ejecutarlo con el array caracteres, tiene un error y creo que tan si quiera contabiliza las veces que sale cada caracter.

Llegado al for de impresiones, se va al catch y imprime el error.

Saludos!

¿Qué error te da? (Imprime en el printiln la e de Exception)

Puede que sea algún carácter especial (Para que dejen de ser especiales los caracteres utiliza la barra "\" antes del carácter especial).

Te recomiendo que utilices foreach en vez de for simple, te ahorra problemas de pasarse o quedarse corto en los arrays; además de ahorrar código.

for (int numero: nVeces)  {
    //Utiliza la variable "numero" en vez de la posición del array "nVeces[idxx]"
}

 

Este es el error que comete el código al llegar al ultimo for:

run:
Ingresa el nombre del documento a analizar con su extension incluida.
guiones.txt
El documento elegido es: guiones.txt
El contenido del archivo es este:
la letra e sale un par de veces
()

Número de carácteres: 33
Número de palabras : 9
Número de líneas:3
Voy a definir los arrays
He definido arrays
java.lang.ArrayIndexOutOfBoundsException: 32
BUILD SUCCESSFUL (total time: 4 seconds)

Entiendo como que trata de utilizar el índice 32 de ese array, y este no existe. Pero no se como evitar que intente tratar ese elemento, por no decir que no realiza las impresiones de los caracteres anteriores(solo letras).

Por no decir que acabo de fijarme en que no utiliza esta parte del código:

System.out.println();
System.out.println("He llegado al for de impresiones.");

Así que el problema debe estar en el while... Pero no alcanzo a ver en que momento exacto peta el programa.

Un saludo Ramón!

El error es por desbordamiento del array (ArrayIndexOutOfBoundsException).

Te pasa que inicializas "nVeces" con la longitud del Array "abecedario". Y en el while, donde sumas uno al indice "idx", estás contando la longitud del array "caracteres", que es mayor que el otro.
Buenas Ramón, gracias por la solución anterior, el método llegó a buen puerto y ya funciona correctamente.

En el mismo proyecto llego a estos dos subproblemas:

· palabra más repetida y número de apariciones (en caso de empate debe mostrar
todas)
· buscar una palabra (muestra el número de línea y columna de cada aparición)

No se por donde cogerlo, ya que nos prohíben el uso de Strings para trabajar los métodos a excepción de prints, por lo que no se como empezar a resolverlos. Después de estos hay dos subprogramas opcionales (para subir nota) :

· buscar un texto (muestra el número de línea y columna de cada aparición) (opcional)
· buscar palabras repetidas, mostrar el número de línea y columna de las palabras que
aparecen dos veces seguidas en el texto (opcional)

que viendo lo que piden, sobreentiendo que se tratan de derivados de los apartados anteriores.

Si pudieras echarme un cable aun que sea con el planteamiento te lo agradecería muchísimo. Un saludo!

Una pista gorda y posible solución a lo que planteas son las expresiones regulares que te explicamos en este artículo. Ahí encontrarás ejemplos de como contar palabras, buscar textos, posicionar una palabra encontrada, etc. Has tenido mucha suerte porque lo acabamos de publicar :)

Evidentemente existen otras opciones, como son recorrer, buscar y contar. Pero es más pesado para hacer lo mismo.

Aquí dependerá que elijas lo que te hayan pedido en clase.