【发布时间】:2014-12-24 03:21:14
【问题描述】:
我有一个简单的std::vector,其中包含一些数字,这些数字是按升序排列的。我想查找一个元素,到目前为止我使用的是:
return std::lower_bound(vec.begin(), vec.end(), needle);
needle 是我要查找的元素。但是,我的向量往往很长(数百万个元素),但大多数时候内容是相对可预测的,如果第一个元素为零,最后一个元素是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 中实现?
【问题讨论】:
-
@ChrisWard1000 向量会有更好的缓存性能。
-
@ChrisWard1000 原因可能是您想要便宜的插件。
-
@ChrisWard1000 因为插入到
set是摊销的,并且前面的算法会生成已经排序的元素,所以对于插入vector来说,IMO 的成本要低得多。 -
@ChrisWard1000 为什么你认为
std::set使用比std::lower_bound更好的算法?它们都是 O(log n),vector通常具有更好的性能。 -
我认为算法的名称是"one-sided binary search"。它不在标准 C++ 库中。