Java 计算大型文本文件的词频
我有一个巨大的文本文件(大于可用的RAM内存)。我需要计算所有单词的频率,并将单词和频率计数输出到一个新文件中。结果应按频率计数的降序排序 我的做法:Java 计算大型文本文件的词频,java,algorithm,data-structures,text-files,word-count,Java,Algorithm,Data Structures,Text Files,Word Count,我有一个巨大的文本文件(大于可用的RAM内存)。我需要计算所有单词的频率,并将单词和频率计数输出到一个新文件中。结果应按频率计数的降序排序 我的做法: 对给定文件进行排序-外部排序 按顺序计算每个单词的频率,将计数存储在另一个文件中(与单词一起) 根据频率计数-外部排序对输出文件进行排序 我想知道是否有更好的方法来做这件事。我听说过基于磁盘的哈希表吗?或者B+树,但以前从未尝试过 注意:我看到过类似的问题,但没有一个需要解决数据大于内存的问题 编辑:根据这些评论,大家一致认为词典实际上应该放在今
编辑:根据这些评论,大家一致认为词典实际上应该放在今天计算机的内存中。但是,让我们假设一个单词词典,它太大了,无法放入内存。如果唯一单词的列表和频率适合内存(而不是文件,只是唯一的单词),您可以使用哈希表按顺序读取文件(无需存储)
然后,您可以根据出现的次数对哈希表的条目进行排序。我将采用
map reduce
方法:
所有独特的单词可能都适合记忆,所以我会使用这种方法:
- 创建字典(
)HashMap
- 逐行阅读这个巨大的文本文件
- 将新词添加到字典中,并将值设置为1
- 将现有单词的值加1
- 按频率对字典排序
- 将已排序的字典中的单词和频率写入新文件
请注意将单词转换为小写或大写。最好的方法是逐行读取文件,并将单词存储到多重映射中(例如)。如果此映射扩展了您的内存,您可以尝试使用键值存储(例如Berkeley JE DB或)。这些键值存储的工作方式类似于地图,但它们将其值存储在硬盘上。我使用MapDB解决了一个类似的问题,速度非常快。您使用的是哪种编程语言?所有不同的单词都比RAM大?如果您只想计算单词数,可以逐行或按文件流读取文件。您不需要将整个文件加载到RAM中。文件中有多少不同的单词?如果你不存储副本,它们会被存储在内存中吗?真的吗?多少公羊?即使是一本完整的词典也可以放入今天的计算机RAM中……因为海报声称,即使是文件中使用的单词词典也不能放入他的微型RAM中(???)我对这个解决方案投+1票-当只有一台机器按顺序进行切片时,这种方法也有效。我按顺序考虑了这种方法,但是如何有效地组合结果呢?对每个结果文件进行单独排序,然后全部打开并逐行读取,决定是否添加结果(相同的单词)和/或根据字母表中的顺序,将哪个单词/nr对写入结果文件。是的,这几乎就是外部排序的作用。除了我们不需要对整个文件进行排序之外,仅仅对切片进行排序就足够了。但是你能把字典里的每个词都分类吗?这会导致更快地搜索未来的单词吗?不会。。。在添加所有单词后对词典进行排序。为什么选择
词典
?该类被标记为过时。@Matteo:我不建议使用字典类。除了过时之外,它也是一个抽象类,没有任何用处。单词字典
的选择基于HashMap
的用途。假设大多数单词不重复。在读取文件大小为1字节(PiB)的内容时,这种方法可以正常工作吗?很酷,我会尝试一下。