计算两个文件中的重复词
Count recurrent words in two files
我有一个代码,可以计算文件中单词的出现次数。我想将它与 2 个文件一起使用,并在分隔的 table 中显示经常出现的(两个文件都包含)单词。你的想法是什么,如何将它与 2 个文件一起使用?
while ((inputLine = bufferedReader.readLine()) != null) {
String[] words = inputLine.split("[ \n\t\r.,;:!?(){}]");
for (int counter = 0; counter < words.length; counter++) {
String key = words[counter].toLowerCase();
if (key.length() > 0) {
if (crunchifyMap.get(key) == null) {
crunchifyMap.put(key, 1);
} else {
int value = crunchifyMap.get(key).intValue();
value++;
crunchifyMap.put(key, value);
}
}
}
}
Set<Map.Entry<String, Integer>> entrySet = crunchifyMap.entrySet();
System.out.println("Words" + "\t\t" + "# of Occurances");
for (Map.Entry<String, Integer> entry : entrySet) {
System.out.println(entry.getKey() + "\t\t" + entry.getValue());
}
您可能应该使用以下(非常粗略的)算法:
- 读取第一个文件并将所有单词存储在
Set words
;
- 读取第二个文件并将所有单词存储在
Set words2
;
- 通过保留
words
中也包含在 words2
中的所有单词来计算相交集:words.retainAll(words2)
words
包含您的最终列表。
请注意,如果将文件读取算法放入类似
的方法中,则可以重用文件读取算法
public Set<String> readWords(Reader reader) {
....
}
统计出现频率
如果您还想知道出现的频率,您应该将每个文件读入一个 Map<String, Integer>
,它将每个单词映射到它在该文件中的出现频率。
新的 Map.merge(...)
函数(自 Java 8 起)简化了计数:
Map<String, Integer> freq = new HashMap<>();
for(String word : words) {
// insert 1 or increment already mapped value
freq.merge(word, 1, Integer::sum);
}
然后应用以下稍微修改过的算法:
- 读取第一个文件并将所有单词存储在
Map wordsFreq1
;
- 读取第二个文件并将所有单词存储在
Map wordsFreq2
;
- 从第一张地图中提取单词:
Set<String> words = wordsFreq1.keySet()
- 通过保留第二张地图中的所有单词来计算交集:
words.retainAll(wordsFreq2.keySet())
- 现在
words
包含所有共同的单词,wordsFreq1
和wordsFreq2
两个文件所有单词的频率。
有了这三种数据结构,你就可以轻松获取你想要的所有信息。示例:
Map<String, Integer> wordsFreq1 = ... // read from file
Map<String, Integer> wordsFreq2 = ... // read from file
Set<String> commonWords = new HashSet<>(wordsFreq1.keySet());
commonWords.retainAll(wordsFreq2.keySet());
// Map that contains the summarized frequencies of all words
Map<String, Integer> allWordsTotalFreq = new HashMap<>(wordsFreq1);
wordsFreq2.forEach((word, freq) -> allWordsTotalFreq.merge(word, freq, Integer::sum));
// Map that contains the summarized frequencies of words in common
Map<String, Integer> commonWordsTotalFreq = new HashMap<>(allWordsTotalFreq);
commonWordsTotalFreq.keySet().retainAll(commonWords);
// List of common words sorted by frequency:
List<String> list = new ArrayList<>(commonWords);
Collections.sort(list, Comparator.comparingInt(commonWordsTotalFreq::get).reversed());
使用类似的代码读取第二个文件,在上一个文件的map中找到:
while ((inputLine = bufferedReader.readLine()) != null) {
String[] words = inputLine.split("[ \n\t\r.,;:!?(){}]");
for (int counter = 0; counter < words.length; counter++) {
String key = words[counter].toLowerCase();
if (key.length() > 0) {
if (crunchifyMap.get(key) == null) {
continue;
} else if(duplicateMap.get(key) == null) {
duplicateMap.put(key, 1);
}
}
}
}
Set<Map.Entry<String, Integer>> duplicateEntrySet = duplicateMap.entrySet();
System.out.println("Duplicate words:");
for (Map.Entry<String, Integer> entry : duplicateEntrySet ) {
System.out.println(entry.getKey());
}
}
我有一个代码,可以计算文件中单词的出现次数。我想将它与 2 个文件一起使用,并在分隔的 table 中显示经常出现的(两个文件都包含)单词。你的想法是什么,如何将它与 2 个文件一起使用?
while ((inputLine = bufferedReader.readLine()) != null) {
String[] words = inputLine.split("[ \n\t\r.,;:!?(){}]");
for (int counter = 0; counter < words.length; counter++) {
String key = words[counter].toLowerCase();
if (key.length() > 0) {
if (crunchifyMap.get(key) == null) {
crunchifyMap.put(key, 1);
} else {
int value = crunchifyMap.get(key).intValue();
value++;
crunchifyMap.put(key, value);
}
}
}
}
Set<Map.Entry<String, Integer>> entrySet = crunchifyMap.entrySet();
System.out.println("Words" + "\t\t" + "# of Occurances");
for (Map.Entry<String, Integer> entry : entrySet) {
System.out.println(entry.getKey() + "\t\t" + entry.getValue());
}
您可能应该使用以下(非常粗略的)算法:
- 读取第一个文件并将所有单词存储在
Set words
; - 读取第二个文件并将所有单词存储在
Set words2
; - 通过保留
words
中也包含在words2
中的所有单词来计算相交集:words.retainAll(words2)
words
包含您的最终列表。
请注意,如果将文件读取算法放入类似
的方法中,则可以重用文件读取算法public Set<String> readWords(Reader reader) {
....
}
统计出现频率
如果您还想知道出现的频率,您应该将每个文件读入一个 Map<String, Integer>
,它将每个单词映射到它在该文件中的出现频率。
新的 Map.merge(...)
函数(自 Java 8 起)简化了计数:
Map<String, Integer> freq = new HashMap<>();
for(String word : words) {
// insert 1 or increment already mapped value
freq.merge(word, 1, Integer::sum);
}
然后应用以下稍微修改过的算法:
- 读取第一个文件并将所有单词存储在
Map wordsFreq1
; - 读取第二个文件并将所有单词存储在
Map wordsFreq2
; - 从第一张地图中提取单词:
Set<String> words = wordsFreq1.keySet()
- 通过保留第二张地图中的所有单词来计算交集:
words.retainAll(wordsFreq2.keySet())
- 现在
words
包含所有共同的单词,wordsFreq1
和wordsFreq2
两个文件所有单词的频率。
有了这三种数据结构,你就可以轻松获取你想要的所有信息。示例:
Map<String, Integer> wordsFreq1 = ... // read from file
Map<String, Integer> wordsFreq2 = ... // read from file
Set<String> commonWords = new HashSet<>(wordsFreq1.keySet());
commonWords.retainAll(wordsFreq2.keySet());
// Map that contains the summarized frequencies of all words
Map<String, Integer> allWordsTotalFreq = new HashMap<>(wordsFreq1);
wordsFreq2.forEach((word, freq) -> allWordsTotalFreq.merge(word, freq, Integer::sum));
// Map that contains the summarized frequencies of words in common
Map<String, Integer> commonWordsTotalFreq = new HashMap<>(allWordsTotalFreq);
commonWordsTotalFreq.keySet().retainAll(commonWords);
// List of common words sorted by frequency:
List<String> list = new ArrayList<>(commonWords);
Collections.sort(list, Comparator.comparingInt(commonWordsTotalFreq::get).reversed());
使用类似的代码读取第二个文件,在上一个文件的map中找到:
while ((inputLine = bufferedReader.readLine()) != null) {
String[] words = inputLine.split("[ \n\t\r.,;:!?(){}]");
for (int counter = 0; counter < words.length; counter++) {
String key = words[counter].toLowerCase();
if (key.length() > 0) {
if (crunchifyMap.get(key) == null) {
continue;
} else if(duplicateMap.get(key) == null) {
duplicateMap.put(key, 1);
}
}
}
}
Set<Map.Entry<String, Integer>> duplicateEntrySet = duplicateMap.entrySet();
System.out.println("Duplicate words:");
for (Map.Entry<String, Integer> entry : duplicateEntrySet ) {
System.out.println(entry.getKey());
}
}