Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 在最多包含40亿整数的未排序数组中查找缺少的32位整数_Algorithm_Binary Search_Programming Pearls - Fatal编程技术网

Algorithm 在最多包含40亿整数的未排序数组中查找缺少的32位整数

Algorithm 在最多包含40亿整数的未排序数组中查找缺少的32位整数,algorithm,binary-search,programming-pearls,Algorithm,Binary Search,Programming Pearls,这是编程珍珠中描述的。我无法理解作者描述的二进制搜索方法。有人能帮忙详细说明一下吗?谢谢 编辑: 我一般能理解二进制搜索。我只是不明白在这种特殊情况下如何应用二进制搜索。如何确定缺失的数字是否在某个范围内,以便我们可以选择另一个。英语不是我的母语,这是我不能很好地理解作者的原因之一。所以,请用简单的英语:) 编辑:谢谢你们的回答和评论!我从解决这个问题中学到的最重要的一课是,二进制搜索不仅适用于排序数组 这是一个包含除一个整数外的所有40亿整数的文件!这就是本案的症结所在 沿着整数列表移动时,计

这是
编程珍珠
中描述的。我无法理解作者描述的二进制搜索方法。有人能帮忙详细说明一下吗?谢谢

编辑: 我一般能理解二进制搜索。我只是不明白在这种特殊情况下如何应用二进制搜索。如何确定缺失的数字是否在某个范围内,以便我们可以选择另一个。英语不是我的母语,这是我不能很好地理解作者的原因之一。所以,请用简单的英语:)


编辑:谢谢你们的回答和评论!我从解决这个问题中学到的最重要的一课是,二进制搜索不仅适用于排序数组

这是一个包含除一个整数外的所有40亿整数的文件!这就是本案的症结所在

  • 沿着整数列表移动时,计算总和
  • 最后,使用公式N*(N+1)/2计算总和,就像存在所有整数一样
  • 从(2)处计算的总和中提取(1)处的总和。这是缺少的整数
  • 例如:
    假设我们有以下序列:93284410617(1到10,5缺失)。当我们按顺序加整数时,我们得到9+3+2+8+4+10+6+1+7=50。从1到10的所有整数之和为10*(10+1)/2=55。因此,缺少的整数是55-50=5。Q.E.D.

    我相信作者的意思是,选择当前整数范围的中点,并准备两个输出文件。读取输入时,中点以上的所有内容都进入一个文件,中点以下的所有内容进入另一个文件

    完成后,选择较小的文件,然后使用[lower bound,Middpoint]或(Middpoint,upper bound]作为新范围重复该操作,直到文件和范围足够小,可以切换到位图模式(或者输出文件中的一个为空)


    Damien

    还有更多关于的信息。引用自:

    “用代表每个整数的二十位来查看这个二进制搜索是很有帮助的。在算法的第一个过程中,我们读取(最多)输入一百万个整数,将前导零位的整数写入一个磁带,将前导一位的整数写入另一个磁带。这两个磁带中的一个最多包含500000个整数,因此我们接下来使用该磁带作为当前输入并重复探测过程,但这次是在第二位。如果原始输入磁带包含N个元素,则第一次读取N个整数,第二次读取最多N/2,第三次读取最多N/4,依此类推,因此总运行时间与N成正比。丢失的整数可以通过在磁带上排序然后扫描找到,但这需要与N log N成正比的时间。”


    如您所见,这是二进制搜索算法的一种变体:将问题分成两部分,然后用其中一个较小的部分来解决问题。

    总体思路是:选择一个整数范围,然后选择该范围内的所有整数。如果整数的数量小于范围的大小,您知道t该范围包含一个或多个缺失的数字


    <>这适用于最初的问题,即你如何知道在第一个地方也有一些缺失的数字。

    如果你考虑的数字在1到n的范围内,其中一半大于n/2,其中一半小于n/2</p> 大于N/2的将使MSB设置为1; 对于较小的,MSB=0

    基于MSB对整个集合进行分区,这将提供两个集合:小于N/2的数字集合和大于N/2的数字集合

    较小的分区缺少元素

    在下一步中,使用下一个MSB

  • 如果较小的集合小于N/2,则其中一半小于N/4(第二个MSB=0),另一半大于N/4(第二个MSB=1)

  • 如果较小的集合大于N/2,则其中一半小于N/2+N/4(第二个MSB=0),另一半大于N/2+N/4(第二个MSB=1)

  • 每一轮搜索将使搜索空间减半,仅此而已

     Sum ( N / 2^i ) for 0 <= i < log N gives you O(N)
    

    Sum(N/2^i)for 0这基本上是与相同的问题。相同的方法适用于获得O(N)的充足内存情况复杂性。基本上只是递归地尝试将每个整数放在其正确的位置,看看有什么不具有正确的值。

    您不了解哪部分?您可以详细说明吗?二进制搜索是另一个问题的解决方案。不适合在未排序的范围内查找值。您不了解的是什么?二进制搜索还是JU作者描述?如果数组未排序。我们可以对数组进行nlog(n)排序(有时我们可以用O(n)进行排序),然后进行二进制搜索日志(n)这是2log(n)时间是顺序搜索的最坏情况。您的问题描述听起来像是所有数字都是0-2^32-1,只有一个数字缺失。假设是这种情况,您可以通过计算应该存在的所有数字的总和来找到缺失的数字(这是静态的)和你们实际拥有的数字之和相比。不,这是一个未排序的范围。然而,你们是正确的,有不止一个差距(问题是最多40亿个整数),这是关于一个最多包含40亿个整数的文件(它可能包含更少的整数),这当然不是int32的整个范围。您必须找到文件中不存在的32位整数中的至少一个。(对于删除的回复很抱歉,我第一次也误读了这个问题)这是问题的一个解决方案。但是,它的伸缩性不太好,也没有按照要求使用二进制搜索。运行总和和目标数N(N+1)/2需要保持在64位。根据什么标准选择上半部分和下半部分?因为元素未排序。@rwwilden-我不是