【问题标题】:How to count the frequency of a word in text file using Java?如何使用Java计算文本文件中单词的频率?
【发布时间】:2012-05-12 13:46:35
【问题描述】:

我有一个大文本文件(大小远高于 1G),我想使用 Java 计算该文件中某个单词的出现次数。文件中的文本写在一行上,因此可能无法逐行检查。解决这个问题的最佳方法是什么?

【问题讨论】:

  • 您遇到的问题是什么?
  • 我曾尝试使用 BufferedReader 逐行读取内容,但在我意识到之间实际上没有换行符之后,我必须使用替代方法。我只是希望文件的大小不会成为 Java 程序的沉重负担。
  • 你的意思是,一个大约 1GB 的文本文件,最后没有换行符?如果是,readLine 将无法使用它。你需要分块阅读。

标签: java word-count text-files


【解决方案1】:

您想使用 Java 的 Scanner 类逐字使用该巨大文件。调用 useDelimiter(...) 方法一次来配置单词的拆分方式(可能只是一个空格字符),然后使用 hasNext() 和 getNext() 循环文件内容。

对于计数本身,为简单起见,您可以使用 HashMap。

【讨论】:

  • 其实我只需要数一个字。这与一些统计数据无关。
  • @God_of_Thunder 没有人会用勺子喂你!
  • @Kazekage Gaara 我有没有请你喂我?不。如果您是这样认为的,请不要发表评论。
  • @Bananeweizen 感谢您的想法。我已经设法使用 Scanner 来完成我需要做的事情。
【解决方案2】:

您可以使用Trie 数据结构的细微变化。此 DS 用于创建单词词典。您要搜索“Stack”的示例,您可以通过传递“Sta”来搜索 trie,它将返回所有以“Sta”开头的单词。

现在在您的问题中,您可以逐字遍历文件并将其放入 trie 中。为每个单词添加额外的字段“计数”。现在,当您插入修改后的尝试时,您可以增加“计数”。现在您可以计算 trie 中的所有单词了。

我认为内存使用量不应过多,因为 1G 文件中的大部分单词都是重复的。您只需遍历文件一次。而且,一旦你有了这个 trie,你就可以搜索多个单词而不会影响性能。

编辑:

如果您需要完全匹配,我必须同意@Bananeweizen 的观点,即 HashMap 也是一个很好的解决方案。所以逐字阅读并放入HashMap。内存使用量应该和try一样。

【讨论】:

    【解决方案3】:

    您首先需要对单词进行排序,使其按字母顺序排列。在读入数据并在空格上拆分单词后,您可以通过多种方式执行此操作。您还需要在排序之前删除特殊字符和标点符号。

    排序后,您要定位的单词都会并排排列,这会使您的搜索成为 O(N) 问题。那时,您可以使用循环结构来遍历并比较每个单词,直到找到单词的第一个实例。在那一点上,你继续循环,计算每个单词,直到你到达下一个单词。

    此时,您知道您的集合中没有该词的更多实例,您可以停止搜索。

    这个特定的搜索算法是 O(N) 最坏的情况。如果您的单词是“apple”,那么搜索完成的速度可能比您的单词是“zebra”要快得多。

    您可以选择其他算法,具体取决于您的具体需求。

    根据您的问题,我假设这是一个编程练习,而不是实际的工作问题。如果是工作问题,那么这个问题已经解决了无数次了,而且有很多 Java 搜索库可以帮助您解决这个问题,包括 Java 标准库中的工具。

    【讨论】:

    • 嗯,这实际上是我工作中的一个问题(我希望这只是一个练习)。我只是想要一个可行的解决方案,因为我怀疑程序运行期间的内存消耗是否会太大。这个程序只是一个工具来证明其他程序的结果,因此它可以在普通的台式计算机上执行,而不是在服务器上。
    • 它可能会导致计算机稍微变慢,但只要它有足够的资源并且只要 JVM 有足够的资源分配给它,你应该没问题。尽管如此,我相信这个算法使用 C++ 会快得多,因为每个单词都可以分配给一个指针。对指向字符串的指针进行排序比对实际字符串本身进行排序要快得多...
    • 也许它与 C++ 一起工作得更好,但这里的效率并不是真正关心的问题。我需要从这个程序中检查该文件中的布局是否是我想要的。所以它只会执行几次,我不再使用它了。
    【解决方案4】:

    您可以使用外部工具构建一些文本索引。之后,您将能够在该索引中快速找到计数不同的单词。 例如。你可以得到 Lucene 来建立这样的索引。然后简单地获取其中的术语频率。有类似的问题counting the word frequency in lucene index 带有文章和代码示例的链接。

    【讨论】:

    • 这个问题有很多更简单的非外部解决方案
    猜你喜欢
    • 2016-01-23
    • 2017-04-03
    • 2015-06-14
    • 2011-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-06
    相关资源
    最近更新 更多