如何使用 1 Kb 或更少的内存在非常大的文件(超过 1 Gb)中搜索最常用的单词?

How do I search most common words in very big file (over 1 Gb) wit using 1 Kb or less memory?

我的文本文件很大,有几千万字,一行一个字。我需要在该文件中找到前 10 个最常见的单词。有一些限制:仅使用标准库和使用少于 1 KB 的内存。

保证该文件中的任何 10 个字都足够短以适应所述内存限制,并且将有足够的内存用于一些其他变量,例如计数器等

我唯一的解决办法是使用另一个文本文件作为额外的内存和缓冲区。但是,处理该问题似乎是一种糟糕且缓慢的方法。

有没有更好更高效的解决方案?

您可以先对这个文件进行排序(内存有限是可能的,但当然需要磁盘 IO - 参见 How do I sort very large files 作为入门)。

然后你将能够逐行读取排序的文件并逐个计算每个单词的频率 - 存储它们,在 10 个单词之后 - 如果频率更高则全部存储在你的数组中 - 将其添加到内部数组并删除最少出现的单词,因此在此阶段您将只保留 10 个最常出现的单词。

正如@John Bollinger 提到的那样 - 如果您的要求是打印所有前 10 个单词,例如 - 来自文件的所有单词都具有相同的频率,即它们都是“顶部”,那么这种方法将不起作用,您需要计算每个单词的频率,存储在文件中,对其进行排序,然后打印前 10 个,包括与第 10 个频率相同的所有单词。

如果您可以创建一个 new 文件,无论它有多大,您都可以创建一个简单的 disk-based tree 数据库来保存每个单词及其出现频率。这将花费你每次 O(log n),n 从 1 到 N 个单词,加上整个 N-sized 树的最终扫描,加起来为 O(N log N)。

如果您不能创建一个新文件,您将需要对整个文件执行in-place排序,这将花费大约 O(N2)。 这更接近于 O((N/k)2),我认为,对于最简单的 bubble-sort - 但这是 O(1/k2)O(N2) = K O(N2) 仍然是 O(N2)。那时你可以最后一次重新扫描文件,在每个单词的每个 运行 之后你就会知道那个单词是否可以进入你的前十名,以及在哪个位置。所以你只需要在内存中放入十二个单词(前十个单词、当前单词和刚从文件中读取的单词)。 1K应该够了。

所以,辅助文件实际上是最快的选项。