c++ - 带提示的二分搜索

标签 c++ algorithm search

我有一个简单的 std::vector 包含一些数字,这些数字是按升序排列的。我想查找一个元素,到目前为止我使用的是:

return std::lower_bound(vec.begin(), vec.end(), needle);

needle 是我要查找的元素。但是,我的 vector 往往很长(数百万个元素),但大多数时候内容是相对可预测的,如果第一个元素为零并且最后一个元素是 N,那么之间的元素具有接近 (N * index)/vec.size() 的值,因此是可预测的。

是否对下限进行了修改,可以接受提示(类似于 std::map::emplace_hint() 的做法),例如:

assert(!vec.empty());
std::vector<int>::iterator hint = vec.begin() + std::min(vec.size() - 1,
    (needle * vec.size()) / vec.back());
if(*hint > needle)
    return std::lower_bound(vec.begin(), hint, needle);
else
    return std::lower_bound(hint, vec.end(), needle);

这会起作用,但是 lower_bound 忽略了它接近解决方案并且很可能会开始将间隔分成两半(看看我们知道针最有可能不是的地方),采取不必要的许多步骤。我知道有一种算法从第 1 步开始,它会加倍直到超过指针,然后在给定的时间间隔内进行二进制搜索。

我忘记了算法的名称是什么。是否在 STL 中实现?

最佳答案

我认为您正在寻找的算法称为 interpolation search这是二分搜索的一种变体,它不是查看数组的中点,而是在数组端点之间线性插值以猜测键应该在哪里。对于按照您的方式构建的数据,预期运行时间为 O(log log n),比标准二分搜索快得多。

这个算法在 C++ 中没有标准实现,但是(作为一个完全无耻的插件)我碰巧用 C++ 编写了这个算法。 My implementation is available online如果您有兴趣了解它的工作原理。

希望这会有所帮助!

关于c++ - 带提示的二分搜索,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26613111/

相关文章:

c++ - 如何创建具有可变元素的 C++ 数组?

c++ - 将字符串化的十六进制字符转换为 std::string

c++ - move 构造函数不会被解雇

algorithm - 如何处理有向图中强连通分量的节点?

c++ - 确定性地检查一个大数是素数还是合数?

c# - 如何使用非前缀关键字从列表中进行搜索

c++ - 内置对象/库的静态初始化顺序失败

c++ - 这个洗牌算法有什么问题吗?

java - 如何获得所有可能的单词?

mysql - mysql 搜索域,没有 TLD 扩展名