找到任意大数的算法

aho*_*ota 3 algorithm

这是我一直在考虑的事情:假设你有一个数字,x,可以是无限大,你必须找出它是什么.所有你知道的是,如果另一个数字y大于或小于x.找到x的最快/最好的方法是什么?

一个邪恶的对手选择了一个非常大的数字......说:

int x = 9^9^9^9^9^9^9^9^9^9^9^9^9^9^9
Run Code Online (Sandbox Code Playgroud)

并提供isX,isBiggerThanXisSmallerThanx功能.示例代码可能如下所示:

int c = 2
int y = 2
while(true)
    if isX(y) return true
    if(isBiggerThanX(y)) fn()
    else y = y^c
Run Code Online (Sandbox Code Playgroud)

其中fn()一个函数是,一旦找到数字y(大于x)就会确定x(比如将数字除以一半并进行比较,然后重复).问题是,因为x是任意大的,所以使用常数来增加y似乎是个坏主意.

这只是我一直想知道的事情,我想听听其他人的想法

Edm*_*und 6

使用二进制搜索,就像通常的"尝试猜测我的号码"游戏一样.但由于没有有限的上限点,我们会在第一阶段找到合适的上端点:

  • 最初任意设置上端点(例如1000000,尽管1或1 ^ 100也可以工作 - 给定无限空间工作,所有有限值同样不成比例).
  • 将神秘数字X与上端点进行比较.
  • 如果它不够大,请加倍,然后再试一次.
  • 一旦上端点大于神秘数字,继续进行正常的二进制搜索.

第一阶段本身类似于二元搜索.不同之处在于,不是每一步都将搜索空间减半,而是将其翻倍!每个阶段的成本是O(log X).一个小的改进是在每个加倍步骤设置低端点:我们知道X至少与前一个高端点一样高,所以我们可以将它重用为低端点.搜索空间的大小在每一步仍然翻倍,但最终它将是原来的一半.二进制搜索的成本将仅减少一步,因此其总体复杂性保持不变.

一些笔记

回应其他评论的几点说明:

这是一个有趣的问题,计算机科学不只是关于物理机器上可以做什么.只要问题可以正确定义,就值得提出并思考.

数字范围是无限的,但任何可能的神秘数字都是有限的.所以上面的方法最终会找到它. 最终定义为,对于任何可能的有限输入,算法将在有限数量的步骤内终止.然而,由于输入是无限制的,步骤的数量也是无限的(只是在每种特定情况下,它将"最终"终止.)

  • 正如我在问题本身的评论中所提到的,我认为误解在于神秘数字本身并不是无限的.它不是**"无限大",而是有限的,尽管是任意大的.这类似于无穷极限的定义,我们让'N`是任意大数. (4认同)
  • @EricJ.不,他是对的.有无限多个整数并不意味着有一个无限整数; 每个整数都是有限的,因此可以通过这种方法在有限时间内找到.考虑到X在某种意义上是随机抽取的,你似乎在考虑寻找时间X的期望值,但这是一个单独的问题(并不一定是明确定义的问题.) (2认同)
  • @EricJ.该算法是合理的,并且对于任何给定的输入总是终止.运行时间受答案大小的限制,对于任何问题实例肯定是有限的. (2认同)
  • @EricJ.我担心我对数字线示例以及与此问题的相关性无法理解.是的,"权利"中有无数个数字,这很明显.但这并不意味着该算法不会终止该点. (2认同)
  • @EricJ:不过,我不确定你的数轴参数是什么。这听起来很像“X上方的数字比X下方的数字无限多,所以如果有人选择某个X,那么必须永远数到X”。毕竟,我总是可以简单地问“是1吗?是2吗?是3吗?”,我会在有限的时间内到达那里,因为**数字是有限的**,尽管你的“不是真的任何可能的神秘数字是有限的”声称。 (2认同)