计算巨大文本文件的字频率

时间:2013-02-07 08:09:31

标签: java algorithm data-structures text-files word-count

我有一个巨大的文本文件(大于可用的RAM内存)。我需要计算所有单词的频率,并将单词和频率计数输出到一个新文件中。结果应按频率计数的降序排序。

我的方法:

  1. 对给定文件进行排序 - 外部排序
  2. 按顺序计算每个单词的频率,将计数存储在另一个文件中(连同单词)
  3. 根据频率计数对输出文件进行排序 - 外部排序。
  4. 我想知道是否有更好的方法来做到这一点。我听说过基于磁盘的哈希表?或B +树,但从未尝试过。

    注意:我在SO上看过类似的问题,但没有一个问题需要解决数据大于内存的问题。

    编辑:根据评论,同意在实践中的字典应该适合今天的计算机的记忆。但是让我们假设一个假设的词典,这个词很大,不适合记忆。

4 个答案:

答案 0 :(得分:13)

我会采用map reduce方法:

  1. 在节点上分发文本文件,假设节点中的每个文本都可以放入RAM中。
  2. 计算节点内的每个单词频率。 (使用hash tables
  3. 将每个结果收集到主节点中并将它们全部合并。

答案 1 :(得分:5)

所有独特的单词可能都适合记忆,所以我会使用这种方法:

  • 创建字典(HashMap<string, int>)。
  • 逐行阅读巨大的文本文件。
  • 在字典中添加新单词并将值设置为1.
  • 将现有单词的值加1。

解析完整个巨大文件后:

  • 按频率对字典排序。
  • 将带有单词和频率的已排序字典写入新文件。

请注意将单词转换为小写或大写。

答案 2 :(得分:2)

实现它的最佳方法是逐行读取文件并将单词存储到Multimap中(例如Guava)。如果此Map扩展了您的内存,您可以尝试使用键值存储(例如Berkeley JE DB或MapDB)。这些键值存储的工作方式与地图类似,但它们将值存储在HDD上。我使用MapDB来解决类似的问题并且速度非常快。

答案 3 :(得分:1)

如果唯一单词和频率列表适合内存(不是文件只是唯一的单词),您可以使用哈希表并按顺序读取文件(不存储它)。

然后,您可以按出现次数对哈希表的条目进行排序。