Как найти 20 самых популярных слов в arraylist - PullRequest
2 голосов
/ 25 сентября 2019

У меня есть задача, где мне дали файл с текстом.Этот текст является частью книги.Моя задача - передать этот файл в arraylist, hashmap (один из тех), который я сделал.Вторая часть работы состоит в том, чтобы найти 20 наиболее часто встречающихся слов из этого файла и отсортировать их в порядке убывания.

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

Итак, первая часть кода будет hashmap

public void findWords() throws Exception {
    // ovde traxim 20 reci koje se najcesce ponavljaju u tekstu
    String line;
    Integer counter = 0;
    FileReader fr = new FileReader("src/Fajl/blab");
    BufferedReader br = new BufferedReader(fr);

    while ((line = br.readLine()) != null) {
        String string[] = line.toLowerCase().split("([,.\\s]+)");
        for (String s : string) {
            if (hashmap.containsKey(s)) {
                counter++;
            } else
                counter = 1;
            hashmap.put(s, counter);
        }
    }

Следующая частьсортировка по значению и отображение количества повторений 20 самых популярных слов, от самого большого до минимального

Collection<Integer> values = mapaKnjiga.values();
    ArrayList<Integer> list = new ArrayList<Integer>(values);
    Collections.sort(list, Collections.reverseOrder());
    for (int i = 0; i < 20; i++)
        System.out.println(list.get(i));
}

Ответы [ 6 ]

1 голос
/ 25 сентября 2019

Рассматривать слова как хэш-карту со словами в качестве ключа и считать как значения.

LinkedHashMap<String, Integer> reverseSortedMap = new LinkedHashMap<>();

words.entrySet()
                .stream()
                .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
                .forEachOrdered(x -> reverseSortedMap.put(x.getKey(), x.getValue()));

List<String> finalList = reverseSortedMap.entrySet()
                                        .stream()
                                        .map(entry -> entry.getKey())
                                        .limit(20)
                                        .collect(Collectors.toList());
0 голосов
/ 25 сентября 2019

спасибо всем за ваши усилия и желание помочь.Я новичок в программировании на Java и в данный момент работаю над своим окончательным проектом для курса.Я нашел решение, которое, на мой взгляд, очень, очень трудно понять, если вы находитесь на этом уровне.Это не мое решение, но оно работает.Сначала я заполнил hashmap значениями из файла, затем я проверил, существует ли это слово в файле, если true counter ++, если false counter = 1.После этого

public void dvadesetNajviseKoriscenih() throws Exception{
    // this is where I populate hashmap with values
    String line;
    Integer counter = 0;
    FileReader fr = new FileReader("src/Fajl/knjiga");
    BufferedReader br = new BufferedReader(fr);

    while ((line = br.readLine()) != null) {
        String string[] = line.toLowerCase().split(" ");
        for (String s : string) {
            // this is where I check if the word already exists
            if (hashmapName.containsKey(s)) {
                counter++; //however this counter here is not right, so I will have to change it.
            } else
                counter = 1;
            hashmapName.put(s, counter);
        }
    } //this below is where it sorts words by number of how many times it repeats...

    Map<String, Integer> sorted = hashmapName.entrySet().stream().sorted(comparingByValue())
            .collect(toMap(e -> e.getKey(), e -> e.getValue(), (e1, e2) -> e2, LinkedHashMap::new));
    sorted = hashmapName.entrySet().stream().sorted(Collections.reverseOrder(Map.Entry.comparingByValue()))
            .limit(20).collect(toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e2, LinkedHashMap::new));
    for (String s : sorted.keySet()) {
        System.out.println(s + " " + sorted.get(s));
    }
}

Если кто-то знает, что происходит в нижней части кода, пожалуйста, не стесняйтесь объяснять нам, новичкам :) И, конечно, оцените мое решение :) Если кто-то хочет попрактиковаться вэту задачу, не стесняйтесь писать мне на github / BojanBosnjak

0 голосов
/ 25 сентября 2019

Предполагая, что ваша функция findWords () работает правильно, где у вас есть все слова и их количество, вы можете выполнить следующее:

Так как вам нужно напечатать счет определенного слова.Таким образом, вы можете начать с определения класса Word с содержимым и количеством свойств и определения компаратора по умолчанию. Примерно так:

class Item implements Comparable<Item>{
   String word;
   int count;

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

public int compareTo(Item word){
    //sorting in descending order
    return word.count - this.count;
}

public String toString(){
    return "Word: " + word +"Count: " + count;
}}

Определить ArrayList элементов для хранения объекта Item:

ArrayList<Item> al = new ArrayList<>();

Вы можете перебирать всю хэш-карту, а затем вставлять каждую пару в виде:

Item item = new Item(word, count);
al.add(item);

И, наконец, вы можете отсортировать список и затем выбрать 20 лучших слов:

Collections.sort(al);
0 голосов
/ 25 сентября 2019

Как насчет использования потокового API:

String[] words = {"one", "two", "two", "three", "three", "three"};
Map<String, Long> result = 
        Arrays.stream(words)
              .collect(Collectors.groupingBy(Function.identity(),
                       Collectors.counting()));

И вторая часть:

List<Long> collect = result.entrySet().stream()
                .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
                .limit(20)
                .map(Map.Entry::getValue)
                .collect(Collectors.toList());
System.out.println(collect);
0 голосов
/ 25 сентября 2019

Предполагая, что вам нужен список из 20 лучших слов и его частота на карте, чтение слов из файла, решение java-8 будет

LinkedHashMap<String, Long> top20WordsByFrequency = null;
    try {
        // Convert a file into stream of lines
        top20WordsByFrequency = Files.lines(Paths.get("src/Fajl/blab"))
                // convert lines into words
                .flatMap(line -> Arrays.stream(line.toLowerCase().split("([,.\\\\s]+)")))
                // make a map by grouping by key as word and value as the count of the word
                .collect(Collectors.groupingBy(Function.identity(), Collectors.counting())).entrySet().stream()
                // sort the map based on values (frequency) in reverse order and limit the map
                // to 20
                .sorted(Entry.comparingByValue(Comparator.reverseOrder())).limit(20)
                // after limiting sort based on keys in descending order
                .sorted(Map.Entry.<String, Long>comparingByKey().reversed())
                // preserve the order in a LinkedHashMap
                .collect(Collectors.toMap(Entry::getKey, Entry::getValue, (u, v) -> u, LinkedHashMap::new));

    } catch (IOException e) {
        e.printStackTrace();
    }
    System.out.println(top20WordsByFrequency);
0 голосов
/ 25 сентября 2019

вы можете создать класс TextCounter и добавить его в список на основе данных, собранных картой

class TextCounter{
  String text;
  int count;
}

и теперь сортировать по значению его счетчика

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