从包含 10 亿个整数的文件中显示前 100 个整数的最有效方法。内存最多可容纳 100 万个整数

Posted

技术标签:

【中文标题】从包含 10 亿个整数的文件中显示前 100 个整数的最有效方法。内存最多可容纳 100 万个整数【英文标题】:Most efficient way to display top 100 integers from a file containing 1 billion integers. Memory can hold at max 1 million integers 【发布时间】:2016-08-14 08:30:50 【问题描述】:

一个文件中存储了 10 亿个整数。每个整数一行。内存可以支持一次加载 100 万个整数。我们需要显示 100 个最大的整数。

我的想法:

    使用大小为 100 的最大堆数据结构。 从文件中取出第 1 百万个整数并放入堆中。

【问题讨论】:

现在是学习优先队列的时候了。 @MBo:我想到了优先队列。它是在堆数据结构中实现的。我可以拥有我读取的前 100 万个数字的最大堆,但接下来呢? 请参阅***.com/questions/7746648/… 了解总体思路。 Retrieving the top 100 numbers from one hundred million of numbers的可能重复 【参考方案1】:

为前 100 个元素构建 min-heap

对于每个新元素检查 - 如果它大于堆顶,删除顶部,插入新元素。

堆大小始终为 100。 所以整体复杂度是 O(N * log(100)) = O(N) (在 k 最高值的常见情况下 - O(N log k))

百万用作您从文件中读取的最大块大小,然后遍历它。

【讨论】:

一般的解是O(n log k),当k相对于n非常小时,它本质上是O(n)。【参考方案2】:

您只需要遍历文件一次:

拥有前 100 个整数的有序列表 遍历文件:如果一个数字足够大,把它放在前 100 位

编辑:如果您使用排序列表和 O(log(n))O(n) /strong> 如果你使用堆。因此,如果进程的性能取决于插入,那么使用堆是有意义的。如果它主要取决于读取文件,那没关系。

【讨论】:

你最终会以这种方式进行 1000 亿次比较。至少应该保持结构有序,以便您可以比较最低的条目。 不,你只比较最低的元素。 只要它是一个有序的结构,是的。刚刚在我的评论中写了。 如果“前 100 个”是排序列表,这将非常昂贵,因为插入列表是 O(n),其中 n 是列表中的项目数。当然,确定项目是否应该进入列表是 O(1),但是你必须遍历列表以确定它将进入哪个位置。所以最坏的情况变成 O(n * 100)。 好吧,似乎找到插入的正确位置是 O(log(n)),但实际上插入是 O(n),因为您必须移动所有后续数字。我将编辑我的答案。

以上是关于从包含 10 亿个整数的文件中显示前 100 个整数的最有效方法。内存最多可容纳 100 万个整数的主要内容,如果未能解决你的问题,请参考以下文章

查找给定 40 亿个整数中不存在的整数 [重复]

编程珍珠:在 40 亿个整数的文件中查找缺失的整数

6.3 40亿个非负整数中找到没出现的数

从10亿个数据中,取出前1000个最大的数

Java 几分钟处理完 30 亿个数据?

如何给100亿个数字排序