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); } }
6 Réponses :
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
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);
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()));
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());
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; }}
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
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.