Sorting words in order of frequency? (least to greatest)

前端 未结 4 2378
孤独总比滥情好
孤独总比滥情好 2021-01-06 07:05

does any one have any idea how to sort a list of words in the order of their frequency (least to greatest) using the built in collection.sort and a compar

4条回答
  •  独厮守ぢ
    2021-01-06 07:41

    First of all your usage of scanner.next() seems incorrect. next() will return the next word and move onto next one every time you call it, therefore the following code:

    if(scanner.next() == null){ ... }
    

    and also

    scanner.next().replaceAll("[^A-Za-z0-9]"," ");
    scanner.next().toLowerCase();
    

    will consume and then just throw away words. What you probably want to do is:

    String word = scanner.next().replaceAll("[^A-Za-z0-9]"," ").toLowerCase();
    

    at the beginning of your while loop, so that the changes to your word are saved in the word variable, and not just thrown away.

    Secondly, the usage of the wordCount map is slightly broken. What you want to do is to check if the word is already in the map to decide what word count to set. To do this, instead of checking for scanner.next() == null you should look in the map, for example:

    if(!wordCount.containsKey(word)){
      //no count registered for the word yet
      wordCount.put(word, 1);
    }else{
      wordCount.put(word, wordCount.get(word) + 1);
    }
    

    alternatively you can do this:

    Integer count = wordCount.get(word);
    if(count == null){
      //no count registered for the word yet
      wordCount.put(word, 1);
    }else{
      wordCount.put(word, count+1);
    }
    

    I would prefer this approach, because it's a bit cleaner, and does only one map look-up per word, whereas the first approach sometimes does two look-ups.

    Now, to get a list of words in descending order of frequencies, you can convert your map to a list first, then apply Collections.sort() as was suggested in this post. Below is a simplified version suited to your needs:

    static List getWordInDescendingFreqOrder(Map wordCount) {
    
        // Convert map to list of  entries
        List> list = 
            new ArrayList>(wordCount.entrySet());
    
        // Sort list by integer values
        Collections.sort(list, new Comparator>() {
            public int compare(Map.Entry o1, Map.Entry o2) {
                // compare o2 to o1, instead of o1 to o2, to get descending freq. order
                return (o2.getValue()).compareTo(o1.getValue());
            }
        });
    
        // Populate the result into a list
        List result = new ArrayList();
        for (Map.Entry entry : list) {
            result.add(entry.getKey());
        }
        return result;
    }
    

    Hope this helps.

    Edit: Changed the comparison function as suggested by @dragon66. Thanks.

提交回复
热议问题