Frage

Ich versuche Häufigkeit von Wörtern in einer Textdatei zu zählen. Aber ich habe einen anderen Ansatz zu verwenden. Zum Beispiel, wenn die Datei enthält BRAIN-ISCHÄMIE und ISCHÄMIE-BRAIN, ich brauche zweimal BRAIN-ISCHÄMIE zu zählen oder umgekehrt (und ISCHÄMIE-BRAIN verlassen). Hier ist mein Stück Code -

// Mapping of String->Integer (word -> frequency) 
    HashMap<String, Integer> frequencyMap = new HashMap<String, Integer>(); 

    // Iterate through each line of the file 
    String[] temp;
    String currentLine; 
    String currentLine2;
    while ((currentLine = in.readLine()) != null) { 

    // Remove this line if you want words to be case sensitive 
    currentLine = currentLine.toLowerCase();
    temp=currentLine.split("-");
    currentLine2=temp[1]+"-"+temp[0];

    // Iterate through each word of the current line 
    // Delimit words based on whitespace, punctuation, and quotes 
    StringTokenizer parser = new StringTokenizer(currentLine);
    while (parser.hasMoreTokens()) { 
    String currentWord = parser.nextToken(); 

    Integer frequency = frequencyMap.get(currentWord); 

    // Add the word if it doesn't already exist, otherwise increment the 
    // frequency counter. 
    if (frequency == null) { 
    frequency = 0; 
    } 
    frequencyMap.put(currentWord, frequency + 1); 
    }
    StringTokenizer parser2 = new StringTokenizer(currentLine2);
    while (parser2.hasMoreTokens()) { 
        String currentWord2 = parser2.nextToken(); 

        Integer frequency = frequencyMap.get(currentWord2); 

        // Add the word if it doesn't already exist, otherwise increment the 
        // frequency counter. 
        if (frequency == null) { 
        frequency = 0; 
        } 
        frequencyMap.put(currentWord2, frequency + 1); 

        } 
    }

    // Display our nice little Map 
    System.out.println(frequencyMap);

Aber für die folgende Datei -

  

ISCHÄMIE-GLUTAMAT   ISCHÄMIE-BRAIN   Glutamat BRAIN   BRAIN-TOLERIEREN   BRAIN-TOLERIEREN   TOLERIEREN-BRAIN   Glutamat ISCHÄMIE   Ischämisch GLUTAMAT

Ich erhalte die folgende Ausgabe -

  

{Glutamat-Hirn = 1, Ischämie-Glutamat = 3, Ischämie-Hirn = 1, Glutamat-Ischämie = 3, Gehirn-tolerieren = 3, Gehirn-Ischämie = 1, tolerieren-Hirn = 3, Gehirn-Glutamat = 1}

Das Problem ist in der zweiten, während Block denke ich. Jedes Licht auf dieses Problem wird sehr geschätzt werden.

War es hilfreich?

Lösung

Von einer Algorithmus Perspektive, können Sie den folgenden Ansatz in Erwägung ziehen:

Für jede Zeichenfolge, geteilt, dann sortieren, dann wieder verbinden (das heißt nehmen DEF-ABC und Konvertit ABC-DEF. ABC-DEF ABC-DEF umwandeln würde). Dann verwenden, als Schlüssel für Ihre Frequenzzählung.

Wenn Sie auf die genaue ursprüngliche Element zu halten, benötigen, sind nur, dass in Ihren Schlüssel - so würde der Schlüssel: Ordnungs (die Wieder kombinierte String) und original

.

Andere Tipps

Disclaimer:. Ich habe den süß Trick vorgeschlagen von Kevin Day für meine Implementierung

Ich möchte immer noch nur schreiben, um Ihnen mitzuteilen, dass die richtige Datenstruktur ( Multiset / Bad ) und die richtigen Bibliotheken ( google-Guave ) wird nicht nur simplify der Code, sondern macht es auch effizient .

Code

public class BasicFrequencyCalculator
{
    public static void main(final String[] args) throws IOException
    {
        @SuppressWarnings("unchecked")
        Multiset<Word> frequency = Files.readLines(new File("c:/2.txt"), Charsets.ISO_8859_1, new LineProcessor() {

            private final Multiset<Word> result = HashMultiset.create();

            @Override
            public Object getResult()
            {
                return result;
            }

            @Override
            public boolean processLine(final String line) throws IOException
            {
                result.add(new Word(line));
                return true;
            }
        });
        for (Word w : frequency.elementSet())
        {
            System.out.println(w.getOriginal() + " = " + frequency.count(w));
        }
    }
}


public class Word
{
    private final String key;

    private final String original;

    public Word(final String orig)
    {
        this.original = orig.trim();
        String[] temp = original.toLowerCase().split("-");
        Arrays.sort(temp);
        key = temp[0] + "-"+temp[1];
    }

    @Override
    public int hashCode()
    {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((getKey() == null) ? 0 : getKey().hashCode());
        return result;
    }

    @Override
    public boolean equals(final Object obj)
    {
        if (this == obj)
        {
            return true;
        }
        if (obj == null)
        {
            return false;
        }
        if (!(obj instanceof Word))
        {
            return false;
        }
        Word other = (Word) obj;
        if (getKey() == null)
        {
            if (other.getKey() != null)
            {
                return false;
            }
        }
        else if (!getKey().equals(other.getKey()))
        {
            return false;
        }
        return true;
    }

    @Override
    public String toString()
    {
        return getOriginal();
    }

    public String getKey()
    {
        return key;
    }

    public String getOriginal()
    {
        return original;
    }
}

Ausgabe

BRAIN-TOLERATE     = 3
ISCHEMIA-GLUTAMATE = 3
GLUTAMATE-BRAIN    = 1
ISCHEMIA-BRAIN     = 1

Vielen Dank allen für Ihre Hilfe. Hier ist, wie ich es gelöst -

// Mapping of String->Integer (word -> frequency) 
    TreeMap<String, Integer> frequencyMap = new TreeMap<String, Integer>(); 

    // Iterate through each line of the file 
    String[] temp;
    String currentLine; 
    String currentLine2;
    while ((currentLine = in.readLine()) != null) { 

    temp=currentLine.split("-");
    currentLine2=temp[1]+"-"+temp[0];

    // Iterate through each word of the current line  
    StringTokenizer parser = new StringTokenizer(currentLine);
    while (parser.hasMoreTokens()) { 
    String currentWord = parser.nextToken(); 

    Integer frequency = frequencyMap.get(currentWord);  
    Integer frequency2 = frequencyMap.get(currentLine2);

    // Add the word if it doesn't already exist, otherwise increment the 
    // frequency counter. 
    if (frequency == null) {
        if (frequency2 == null)
            frequency = 0;
        else {
            frequencyMap.put(currentLine2, frequency2 + 1);
            break;
        }//else
    } //if (frequency == null)

    frequencyMap.put(currentWord, frequency + 1);
    }//while (parser.hasMoreTokens())

    }//while ((currentLine = in.readLine()) != null)

    // Display our nice little Map 
    System.out.println(frequencyMap);
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top