Ich habe einmal darüber meditiert, wie man performant die Word-Frequenzen eines Textes ermittelt, wobei aber der aktuelle Stand jederzeit geordnet abrufbar sein soll (ansonsten ist das Problem trivial). Ich bin nur auf ein umständliches Hin und Her mit zwei Maps gekommen. Denke ich hier zu kompliziert?
Java:
public class WordCount {
private final Map<String, Integer> wordFreq = new HashMap<String, Integer>();
private final SortedMap<Integer, Set<String>> freqWord = new TreeMap<Integer, Set<String>>();
public void add(String word) {
int freq = 1;
if (wordFreq.containsKey(word)) { //wir müssen den alten Eintrag löschen
freq = wordFreq.get(word);
Set<String> set = freqWord.get(freq);
set.remove(word);
if(set.isEmpty()) { //Einträge mit leeren Sets vermeiden
freqWord.remove(freq);
}
freq++;
}
wordFreq.put(word, freq);
Set<String> set = freqWord.get(freq);
if (set == null) { //Eintrag mit neuem Set anlegen
set = new TreeSet<String>();
freqWord.put(freq, set);
}
set.add(word);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
for (Entry<Integer, Set<String>> entry : freqWord.entrySet()) {
sb.append(entry.getKey()).append(":").append(entry.getValue()).append("\n");
}
return sb.toString();
}
public static void main(String[] args) {
WordCount wc = new WordCount();
wc.add("a");
wc.add("b");
wc.add("a");
wc.add("a");
wc.add("c");
System.out.println(wc);
System.out.println();
wc.add("d");
wc.add("d");
System.out.println(wc);
}
}