我想编写一个程序来显示例如文本中重复次数最多的 5 个单词。 保存在map中的文本的单词,它的键是单词,它的值是重复该单词的次数。
这个程序显示了最重复的单词,但我不知道如何改进它以显示 5 个最重复的单词(以及如何使用 map 而不是列表)。
import java.io.BufferedReader;
import java.io.FileReader;
import java.util.ArrayList;
public class MostRepeatedWord {
public static void main(String[] args) throws Exception {
String line, word = "";
int count = 0, maxCount = 0;
ArrayList<String> words = new ArrayList<String>();
//Opens file in read mode
FileReader file = new FileReader("data.txt ");
BufferedReader br = new BufferedReader(file);
//Reads each line
while((line = br.readLine()) != null) {
String string[] = line.toLowerCase().split("([,.\\s]+) ");
//Adding all words generated in previous step into words
for(String s : string){
words.add(s);
}
}
//Determine the most repeated word in a file
for(int i = 0; i < words.size(); i++){
count = 1;
//Count each word in the file and store it in variable count
for(int j = i+1; j < words.size(); j++){
if(words.get(i).equals(words.get(j))){
count++;
}
}
//If maxCount is less than count then store value of count in maxCount
//and corresponding word to variable word
if(count > maxCount){
maxCount = count;
word = words.get(i);
}
}
System.out.println("Most repeated word: " + word);
br.close();
}
}
最佳答案
这是其中一种情况,其中函数式风格可以导致代码更短——并且希望更易于理解!
一旦你有了words
列表,你就可以简单地使用:
words.groupingBy{ it }
.eachCount()
.toList()
.sortedByDescending{ it.second }
.take(5)
groupingBy()
创建一个 Grouping从单词列表中。 (通常,您会提供一个键选择器函数,解释将项目分组的内容,但在这种情况下,我们需要单词本身,因此是 it
。)因为我们只关心 出现次数,eachCount()
获取计数。 (感谢 Ilya 和 Tenfour04 的这一部分。)
然后我们将 map 转换为列表,准备进行排序。该列表由对组成,单词作为第一个值,计数作为第二个值。
因此 sortedByDescending{ it.second }
按计数排序。因为我们按降序排序,所以最常用的词排在最前面。
最后,take(5)
从列表中获取前五个值,这将是五个最常见的单词(连同它们的计数)。
例如,当我在几个简单的句子上运行它时,它给出了:[(the, 4), (was, 3), (it, 3), (a, 2), (of, 2)]
.
(如果您只想要单词,而不是计数,则可以使用 .map{it.first}
。此外,正如 Tenfour04 所建议的那样,有更好的方法可以从文本中提取单词;但是一旦你开始考虑大小写、撇号、连字符、非 ASCII 字母等,这就会变得非常复杂——并且看起来像是一个与获取最常见单词不同的问题。)
关于java - 如何在 map 中获得 5 个最重复的元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58820410/