假设我有等间隔的双精度数(64位浮点数)x0,x1,...,xn
。等间距意味着对于所有i
,x(i+1) - xi
是恒定的;将其称为w
以获取宽度。
如果y
范围内的数字为[x0,xn]
,我希望找到最大的i
xi <= y
。
一种天真的方法会依次访问每个i
(O(n)
)。最好的是使用二分搜索(O(log n)
)。
常量时间查找将计算(y-x0)/w
并将其转换为整数。但是,由于浮点不准确,这偶尔会产生错误的结果。例如。假设从0开始有100个宽度为0.01的间隔。
(int)(0.29/0.01) = 28 //want 29 here
我可以保留常量时间查找但确保结果始终与二进制搜索相同吗?使用小数而不是“w”和“x0”的双精度执行计算似乎在这里工作,但它会一直有效吗?我总是可以跟随直接查找,并与x
的任何一方进行比较,但这看起来很丑陋且效率低下。
澄清 - 我被赋予xi
和值y
为双倍 - 我无法改变这一点。但是在返回整数索引之前执行的任何中间计算都可以使用我喜欢的任何数据类型。此外,我可以执行一次性的“准备”工作,以便更快地进行运行时计算。
编辑:道歉 - 事实证明我没有正确地检查“等间距” - 当使用浮点运算计算它们的差值时,这些数字通常不是“等距”。
答案 0 :(得分:3)
执行以下操作
计算(int)(0.29/0.01) = 28 //want 29 here
接下来,在28-1和28 + 1之间计算i的i * 0.01
,然后选择正确的那个。
答案 1 :(得分:0)
你是什么意思equally spaced
?如果可以对数字做出一些假设 - 例如 - 它们在一个区间内增加,你实际上可以使用中位数选择,在最好的情况下是O(1),在最坏的情况下是O(log2(N))。