计算大文本文件中指定单词的出现次数

时间:2010-04-20 03:04:38

标签: java algorithm

这是一个面试问题,应该关注效率。如何计算大文本文件中指定单词的出现次数?在大多数编程语言中我只能想到indexOf()方法,但我不认为这是正确的答案。

4 个答案:

答案 0 :(得分:2)

识别单词出现的最佳方法,而不是恰好作为文件行的子字符串出现的字符序列,可能是使用正则表达式Pattern编译的\bword\b - \b是“字边界”。

一旦你有了Pattern,就没有直接的方法来计算一行中出现的次数,所以你需要一些基准来找出更快的结果 - split(取长度)生成的字符串数减去1),不太可能,或者使用模式的Matcher方法生成matcher然后在计数时循环find方法(我是打赌这个),或者别的什么。但是,自己检测单词边界就足够了PITA,我倾向于总是使用正则表达式来完成任务; - )。

有可能通过一次读取(并计算单词出现次数)超过一行来挤压一些速度 - 比如说一次一MB。但是如果你这样做那么你必须注意兆字节中的最后一个“部分”行,因为这个单词的出现可能会在该部分行的结尾和下一个gulp的开始之间分开 - 可行但是,由于引入错误很容易,因此优化的类型只会受到胁迫; - )。

答案 1 :(得分:2)

你想要的是Boyer-Moore algorithm。对于这个问题,它是最有效的已知通用方法。

答案 2 :(得分:0)

如果文本文件非常大,indexOf()可能不是一个好主意,因为您需要将整个文件加载到字符串中,从而咀嚼内存。如果有足够的数据,你就会崩溃程序。我认为您需要查看流读取API以使用indexOf()扫描更实用的块来读取文件。

答案 3 :(得分:0)

使用buffered stream char-by-char将数据读入数组,直到遇到空白字符或其中的一组(空格,制表符,换行符......),将该数组的内容与目标词进行比较,增加计数器如果匹配,清除阵列,返回阅读。

预分配足够大小的数组并重新使用它进行读取,如果需要可以增长它,不要在每次迭代时分配它。实际上不要每次清除数组,只需将其读计数器设置为零。

此外,您可以将char的读取与将其与目标进行比较组合成单个循环,从而消除对中间阵列的需求。第一个变体很容易转换成这个变体,只需抛出数组并在运行中进行比较,你只需知道当前的char及其在单词中的位置。