从包含 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 万个整数的主要内容,如果未能解决你的问题,请参考以下文章