1
votes

Comment trouver les 20 mots les plus fréquents dans Arraylist

J'ai une tâche où j'ai reçu un fichier avec du texte. Ce texte fait partie d'un livre. Ma tâche est de transférer ce fichier dans arraylist, hashmap (l'un de ceux-ci), ce que j'ai fait. La deuxième partie du travail consiste à trouver les 20 mots les plus fréquents de ce fichier et à les trier par ordre décroissant.

Jusqu'à présent, j'ai inséré tous ces mots du fichier dans hashmap et dans arraylist (le code est fourni ci-dessous), j'ai fait ces deux choses dans des méthodes distinctes. La méthode hashmap ne renvoie que des nombres, tandis que arraylist ne renvoie que le mot le plus fréquent, avec le nombre de répétitions.

La première partie du code sera donc hashmap

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));
}

La partie suivante consiste à trier par valeur et à afficher le nombre de répétitions des 20 premiers mots, du plus au moins

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);
        }
    }


8 commentaires

bonjour, pouvez-vous ajouter votre code?


où est le code?


veuillez fournir le code pour voir ce que vous avez fait jusqu'à présent


Désolé, j'ai dû passer de win à linux, le code est bientôt là


ce dont vous avez besoin est de trier la carte par valeurs dans l'ordre décroissant. Vérifiez ceci par exemple howtodoinjava.com/sort/java-sort-map- par valeurs


Vous voulez le top 20 des mots ou la fréquence?


@ chaitanya89 les deux


@TavernaJoe J'ai mis à jour ma réponse selon vos besoins, veuillez vérifier si cela fonctionne.


6 Réponses :


0
votes

vous pouvez créer une classe TextCounter et l'ajouter à une liste basée sur les données collectées par la carte

class TextCounter{
  String text;
  int count;
}

et maintenant trier par sa valeur de compte


0 commentaires

0
votes

En supposant que vous vouliez une liste des 20 premiers mots et leur fréquence dans une carte, en lisant les mots d'un fichier, une solution java-8 serait

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 commentaires

0
votes

Qu'en est-il de l'utilisation de l'API de flux:

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);

Et la deuxième partie:

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


0 commentaires

0
votes

Considérez les mots comme votre hashmap avec des mots comme clé et comptez comme des valeurs.

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 commentaires

0
votes

En supposant que votre fonction findWords () fonctionne correctement, où vous avez tous les mots et leur nombre, vous pouvez suivre:

Puisque vous devez imprimer le nombre d'un mot particulier. Vous pouvez donc commencer par définir une classe Word avec le contenu et le nombre de propriétés, et définir un comparateur par défaut. Quelque chose comme ceci:

Collections.sort(al);

Définissez une ArrayList d'éléments pour contenir l'objet Item :

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

Vous pouvez parcourir la carte de hachage, puis insérer chaque paire comme:

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

Et enfin, vous pouvez trier la liste, puis choisissez les 20 premiers mots:

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;
}}


0 commentaires

0
votes

merci à tous pour vos efforts et votre volonté de vous aider. Je suis débutant en programmation Java et en ce moment je travaille sur mon projet final de cours. J'ai trouvé la solution, qui à mon avis est très, très difficile à comprendre si vous êtes sur ce niveau. Ce n'est pas ma solution, mais ça marche. J'ai d'abord rempli hashmap avec les valeurs du fichier, puis j'ai vérifié si ce mot existe déjà dans le fichier, si vrai compteur ++, si faux compteur = 1. Après cela

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));
    }
}

Si quelqu'un sait ce qui se passe au bas du code, n'hésitez pas à nous l'expliquer, noobs :) Et bien sûr, évaluez ma solution :) Si quelqu'un veut s'entraîner sur cette tâche, n'hésitez pas à m'écrire sur github / BojanBosnjak


0 commentaires