Как отсортировать слова по частоте

1

Я беру входной текстовый файл, преобразовываю его в массив, сортирую массив, а затем получаю частоты каждого слова. Я не могу понять, как сортировать их по их частотам, от самого высокого до самого низкого, не импортируя много вещей (это то, что я пытаюсь сделать):

//find frequencies
    int count = 0;
    List<String> list = new ArrayList<>();
    for(String s:words){
        if(!list.contains(s)){
            list.add(s);
        }
    }
    for(int i=0;i<list.size();i++){
        for(int j=0;j<words.length;j++){
            if(list.get(i).equals(words[j])){
                count++;
            }
        }

        System.out.println(list.get(i) + "\t" + count);
        count=0;
    }

Это возвращает слова со своими частотами в несортированном порядке, например:

the 3
with 7
he 8

и т.п.

Я хочу, чтобы это было отсортировано следующим образом:

he 8
with 7
the 3
Теги:
sorting
word-frequency

4 ответа

1
Лучший ответ

Я реализовал его так,

private static class Tuple implements Comparable<Tuple> {
    private int count;
    private String word;

    public Tuple(int count, String word) {
        this.count = count;
        this.word = word;
    }

    @Override
    public int compareTo(Tuple o) {
        return new Integer(this.count).compareTo(o.count);
    }
    public String toString() {
        return word + " " + count;
    }
}

public static void main(String[] args) {
    String[] words = { "the", "he", "he", "he", "he", "he", "he", "he",
            "he", "the", "the", "with", "with", "with", "with", "with",
            "with", "with" };
    // find frequencies
    Arrays.sort(words);
    Map<String, Integer> map = new HashMap<String, Integer>();
    for (String s : words) {
        if (map.containsKey(s)) {
            map.put(s, map.get(s) + 1);
        } else {
            map.put(s, 1);
        }
    }
    List<Tuple> al = new ArrayList<Tuple>();
    for (Map.Entry<String, Integer> entry : map.entrySet()) {
        al.add(new Tuple(entry.getValue(), entry.getKey()));
    }
    Collections.sort(al);
    System.out.println(al);
}

Выход,

[the 3, with 7, he 8]
  • 0
    Мне нравится, как это сортирует частоты, но мне нужно, чтобы вывод был в порядке убывания - от наибольшего к низшему и в виде таблицы, как в моем коде.
  • 1
    @nanachan Затем измените CompareTo для return new Integer(o.count).compareTo(this.count); и метод toString должен использовать \t .
Показать ещё 3 комментария
2

Я бы предложил использовать небольшой вспомогательный класс:

class WordFreq implements Comparable<WordFreq> {
   final String word;
   int freq;
   @Override public int compareTo(WordFreq that) {
     return Integer.compare(this.freq, that.freq);
   }
}

Создайте массив экземпляров этого класса, по одному для каждого слова, затем отсортируйте массив с помощью массива Arrays.sort.

0

Используйте Map<String, Integer> вместо этого, чтобы сохранить как свой String как ключ, так и значение частоты, с начальным значением 1. Если слово уже существует, просто обновите значение, увеличив его на 1. Затем преобразуйте эту карту в Map<Integer, List<String>> (или Multimap Guava) и используйте значения Integer как ключи и клавиши String чтобы сохранить их как значения.

0

Вы должны создать объект типа Word который содержит слово String value и его частоту.

Затем вы можете реализовать compareTo или использовать Comparator и вызвать Collections.sort() в своем списке типа Word

Ещё вопросы

Сообщество Overcoder
Наверх
Меню