Java: ocurrencia cómputo de palabras, palabras programa cuenta 'vacíos'

lkilgoretrout:

Tengo un programa que toma la entrada desde un archivo de texto, elimina la puntuacion y luego se divide por un solo espacio y coincide los resultados en un mapa. Puedo conseguir que funcione pero estoy consiguiendo un resultado vacío en el mapa, así y no sé lo que da:

escáner toma una entrada:

try
        {
            Scanner input = new Scanner(file);
            String nextLine;
            while (input.hasNextLine())
            {
                nextLine = input.nextLine().trim();
                processLine(nextLine, occurrenceMap);
            }
            input.close();
        }
        catch(Exception e) { System.out.println("Something has gone wrong!");}

El archivo de texto que se pullinng de una versión king james de la biblia entonces una función separada procesa cada línea:

//String[] words = line.replaceAll("[^a-zA-Z0-9 ]", " ").toLowerCase().split("\\s+"); // runtime for  bible.txt is ~1600ms

// changed to simple iteration and the program ran MUCH faster:

char[] letters = line.trim().toCharArray();
for (int i=0; i<letters.length; i++)
{
    if (Character.isLetterOrDigit(letters[i])) {continue;}
    else {letters[i] = ' ';}
}

String punctuationFree = new String(letters);
String[] words = punctuationFree.toLowerCase().split("\\W+");

// add each word to the frequency map:
for (int i=0; i<words.length; i++)
{
    if (! map.containsKey(words[i]))
    {
        map.put(words[i], 1);
    }
    else
    {
        int value = (int)map.get(words[i]);
        map.put(words[i], ++value);
    }
}

Como se puede ver por primera vez lo hice con una sustitución de todo, y luego me vine con mi propio método iterativo cobarde (que parece correr más rápido). En ambos casos, cuando imprimo los resultados utilizando PrintStream Me estoy haciendo una extraña entrada por el principio:

num occurences/ (number /word)

25307 :     // what is up with this empty value ?
1 : 000     // the results continue in sorted order
2830 : 1
2122 : 10
6 : 100
9 : 101
29 : 102
23 : 103
36 : 104
46 : 105
49 : 106

He intentado cambiar String[] words = punctuationFree.toLowerCase().split("\\W+");a .split ( "\ s +") y .split (" "), pero todavía estoy consiguiendo este valor vacío en los resultados.

Estoy tratando sólo para contar las apariciones de palabras y números, ¿por qué estoy recibiendo este valor vacío?

ACTUALIZACIÓN: la sugerencia de que Character.isLetterOrDigit () podría estar regresando caracteres no deseados Reescribí los cheques como por lo que sólo para obtener caracteres que quiero. Yo, sin embargo, todavía estoy recibiendo un valor misterio vacío:

for (int i=0; i<letters.length; i++)
    {
        if ((letters[i] >= 'a' && letters[i] <= 'z') || 
           (letters[i] >= 'A' && letters[i] <= 'Z'))
           {continue;}
        else if (letters[i] >= '0' && letters[i] <= '9')
           {continue;}
        else if ((letters[i] == ' ')||(letters[i] =='\n')||(letters[i] == '\t'))
           {continue;}
        else
            letters[i] = ' ';
    }
Jeff:

Sólo una suposición, pero el método de caracteres IsLetterOrDigitestá definido para trabajar en todo el rango de Unicode. Por el documento página , que incluye todas las "cartas válidos y los dígitos decimales son miembros de las siguientes categorías en UnicodeCategory: UppercaseLetter, LowercaseLetter, TitlecaseLetter, ModifierLetter, OtherLetter o DecimalDigitNumber."

Creo que este método es mantener Caracteres (ModifierLetter y / o OtherLetter en particular) que no desea y que no están incluidos en su fuente por lo que no se pueden ver.

Editar 1 : He probado el algoritmo. Resulta que una línea en blanco elude las pruebas, ya que se salta el bucle. Es necesario añadir una longitud de línea justo después de leer una línea desde la línea de este archivo:

if (nextLine.length() == 0) {continue;}

Editar 2 : También, puesto que va a escanear todos los personajes a eliminar a los "no-palabra y no cifras", usted podría también incorporar la lógica para crear las palabras y añadirlas a la colección. Como esto puede que:

private static void WordSplitTest(String line) {
    char[] letters = line.trim().toCharArray();

    boolean gotWord = false;

    String word = "";

    for (int i = 0; i < letters.length; i++) {
        if (!Character.isLetterOrDigit(letters[i])) {

            if(!gotWord) {continue;}

            gotWord = false;

            AddWord(word);
        }
        if (gotWord) {
            word += Character.toString(letters[i]);
        }
    }
}

private static void AddWord(String word) {
    if (!map.containsKey(word)) {
        map.put(word, 1);
    } else {
        int value = (int) map.get(word);
        map.put(word, ++value);
    }
}

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=283503&siteId=1
Recomendado
Clasificación