Java: получение 500 самых распространенных слов в тексте через HashMap - PullRequest
2 голосов
/ 13 апреля 2011

Я храню свой счетчик слов в поле значения HashMap. Как я могу получить 500 главных слов в тексте?

 public ArrayList<String> topWords (int numberOfWordsToFind, ArrayList<String> theText) {

        //ArrayList<String> frequentWords = new ArrayList<String>();

        ArrayList<String> topWordsArray= new ArrayList<String>();

        HashMap<String,Integer> frequentWords = new HashMap<String,Integer>();

        int wordCounter=0;

        for (int i=0; i<theText.size();i++){



                  if(frequentWords.containsKey(theText.get(i))){

                       //find value and increment
                      wordCounter=frequentWords.get(theText.get(i));
                      wordCounter++;
                      frequentWords.put(theText.get(i),wordCounter);

                  }

                else {
                  //new word
                  frequentWords.put(theText.get(i),1);

                }
        }


        for (int i=0; i<theText.size();i++){

            if (frequentWords.containsKey(theText.get(i))){
                 // what to write here?
                frequentWords.get(theText.get(i));

            }
        }
        return topWordsArray;
    }

Ответы [ 3 ]

4 голосов
/ 14 апреля 2011

Еще один подход, который вы можете рассмотреть, - подумать об этом по-другому: действительно ли Карта является правильным концептуальным объектом здесь?Можно подумать, что это хорошее использование структуры данных, которой так много пренебрегают в Java, bag .Сумка похожа на set , но позволяет предмету быть в наборе несколько раз.Это значительно упрощает «добавление найденного слова».

Google's guava-library предоставляет структуру Bag, хотя там она называется Multiset.Используя Multiset, вы можете просто вызвать .add() один раз для каждого слова, даже если оно уже там.Еще проще, однако, вы можете выбросить свою петлю:

Multiset<String> words = HashMultiset.create(theText);

Теперь у вас есть мультисеть, что вы делаете?Ну, вы можете позвонить entrySet(), что даст вам набор Multimap.Entry объектов.Затем вы можете вставить их в List (они входят в Set) и отсортировать их, используя Comparator.Полный код может выглядеть так (используя несколько других необычных функций Guava, чтобы показать их):

Multiset<String> words = HashMultiset.create(theWords);

List<Multiset.Entry<String>> wordCounts = Lists.newArrayList(words.entrySet());
Collections.sort(wordCounts, new Comparator<Multiset.Entry<String>>() {
    public int compare(Multiset.Entry<String> left, Multiset.Entry<String> right) {
        // Note reversal of 'right' and 'left' to get descending order
        return right.getCount().compareTo(left.getCount());
    }
});
// wordCounts now contains all the words, sorted by count descending

// Take the first 50 entries (alternative: use a loop; this is simple because
// it copes easily with < 50 elements)
Iterable<Multiset.Entry<String>> first50 = Iterables.limit(wordCounts, 50);

// Guava-ey alternative: use a Function and Iterables.transform, but in this case
// the 'manual' way is probably simpler:
for (Multiset.Entry<String> entry : first50) {
    wordArray.add(entry.getElement());
}

и все готово!

1 голос
/ 13 апреля 2011

Здесь вы можете найти руководство, как отсортировать HashMap по значениям.После сортировки вы можете просто перебрать первые 500 записей.

0 голосов
/ 13 апреля 2011

Посмотрите на TreeBidiMap, предоставляемый пакетом Apache Commons Collections.http://commons.apache.org/collections/api-release/org/apache/commons/collections/bidimap/TreeBidiMap.html

Позволяет сортировать карту по ключу или заданному значению.

Надеюсь, это поможет.

Чжунсянь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...