【发布时间】:2016-01-10 13:25:33
【问题描述】:
我已经多次使用此算法对Ints 或Longs 进行二分搜索。基本上,我从Long.MinValue 和Long.MaxValue 开始,并决定根据我最大化(或最小化)的函数的值将位设置在ith 位置。在实践中,这被证明更快(确切地说是 63*2 位运算)并且更容易编码,并且避免了许多 gotchas of traditional binary search implementations。
这是我在 Scala 中的算法:
/**
* @return Some(x) such that x is the largest number for which f(x) is true
* If no such x is found, return None
*/
def bitBinSearch(f: Long => Boolean): Option[Long] = {
var n = 1L << 63
var p = 0L
for (i <- 62 to 0 by -1) {
val t = 1L << i
if (f(n + t)) n += t
if (f(p + t)) p += t
}
if (f(p)) Some(p) else if (f(n)) Some(n) else None
}
我有 3 个问题:
这个算法在文献中叫什么?当然,我不能成为这个的发明者 - 但是,当我尝试谷歌搜索二进制搜索+位掩码/切换的各种组合时,我没有找到任何东西。我个人一直称它为“bitBinSearch”。我完全没有看到在对
Int或Long域进行二进制搜索的文章中提到这一点,而这将是微不足道的。无论如何都可以改进/缩短代码吗?现在我在
n和p中跟踪消极和积极的解决方案。有什么聪明的方法可以将它们合并为单个变量吗?以下是一些示例测试用例:http://scalafiddle.net/console/70a3e3e59bc61c8eb7acfbba1073980c 在您尝试回答之前是否有可以与
Doubles 和Floats 一起使用的版本?
【问题讨论】:
-
我认为位切换是一个实现细节,并不重要:该算法仍然称为二进制搜索。
-
@Bergi:澄清一下-我知道算法通常仍然是二进制搜索;但是,这个具体的实现叫什么?
-
改进了吗?您不需要每次都将 t 移动 i ,而是可以移动一个常数。将 t 初始化为 1
标签: algorithm scala bit-manipulation binary-search bitmask