根据草稿N4431,算法库中的函数std::binary_search
返回bool
,[binary.search]:
template<class ForwardIterator, class T> bool binary_search(ForwardIterator first, ForwardIterator last, const T& value); template<class ForwardIterator, class T, class Compare> bool binary_search(ForwardIterator first, ForwardIterator last, const T& value, Compare comp);
需要:
e
的元素[first,last)
根据表达式e < value
和!(value < e)
或comp(e, value)
进行分区,!comp(value, e)
。此外,对于e
的所有元素[first,last)
,e < value
隐含!(value < e)
或comp(e, value)
implies !comp(value, e)
。如果
true
范围内的迭代器i
满足相应的条件,则返回:[first,last)
:!(*i < value) && !(value < *i)
或comp(*i, value) == false && comp(value, *i) == false
。复杂性:最多log 2 (last-first)+ O(1)比较。
有谁知道为什么会这样?
大多数其他泛型算法要么将迭代器返回到元素,要么迭代器等效于表示元素序列末尾的迭代器(即,序列中要考虑的最后一个元素之后的迭代器),这是什么我原以为是。
答案 0 :(得分:8)
1994年版STL中此函数的名称为var r = /(\/([A-Za-z0-9\.]+)(\??|\/?|$))+/;
r.exec("http://Home/Billing/Index.html?param1=2&another=2")[2]; //outputs: Index.html
r.exec("http://Home/Billing/Index.html/"); //outputs: Index.html
。我认为您同意具有该名称的函数应返回isMember
http://www.stepanovpapers.com/Stepanov-The_Standard_Template_Library-1994.pdf
答案 1 :(得分:2)
它在C ++中被分成多个不同的功能,因为推理它几乎不可能分辨为什么有人以这种或那种方式做某事。 binary_search
会告诉您这样的元素是否存在。如果您需要知道它们的位置,请使用lower_bound
和upper_bound
分别给出开始/结束迭代器。还有equal_range
同时为您提供了开始和结束。
由于其他人似乎认为它显然是为什么以这种方式创造的,因此我会说明我的观点,如果你不是亚历山大·斯捷潘诺夫或和他一起工作的人。
可悲的是,SGI STL FAQ根本没有提到binary_search
。它解释了list<>::size
为线性时间或pop
返回void
的推理。他们认为binary_search
非常特殊,无法记录它。
让我们来看看@ user2899162提到的可能的性能提升:
您可以找到SGI STL算法binary_search
here的原始实现。看一下它可以简化它(我们都知道标准库中的内部名称有多糟糕):
template <class ForwardIter, class V>
bool binary_search(ForwardIter first, ForwardIter last, const V& value) {
ForwardIter it = lower_bound(first, last, value);
return it != last && !(value < *it);
}
正如您所看到的,它是以lower_bound
的形式实现的,并且具有相同的确切性能。如果他们真的希望它能够利用可能的性能改进,那么他们就不会以较慢的方式实现它,所以看起来他们就是这样做的原因并不是这样。
现在让我们看一下它只是一个便利功能
它只是一种便利功能似乎更有可能,但通过STL你可以找到许多其他可能的算法。看看上面的实现,你会发现它比std::find(begin, end, value) != end;
更容易做,但是我们必须一直写这个并且不具备返回的便利功能一个bool
。为什么在这里,而不是所有其他算法呢?它并不是很明显,也不能简单地解释。
总之,我发现它远非显而易见,而且我不知道自己是否能够自信而诚实地回答它。
答案 2 :(得分:2)
二进制搜索算法依赖于严格的弱排序。意味着元素应根据operator <
或根据具有相同保证的自定义比较器进行分区。这意味着,对于给定查询,不一定只能找到一个元素。因此,您需要lower_bound
,upper_bound
和equal_range
函数来检索迭代器。
答案 3 :(得分:0)
标准库包含返回迭代器的二进制搜索算法的变体。它们被称为std::lower_bound和std::upper_bound。我认为std::binary_search
返回bool背后的基本原理是,在等效元素的情况下,它不会清楚返回的迭代器,而在std::lower_bound
和std::upper_bound
的情况下,它很清楚
也可能存在性能因素,因为理论上std::binary_search
可以实现在多个等效元素和某些类型的情况下更好地执行。但是,标准库(libstdc++
)的至少一个流行实现使用std::binary_search
实现std::lower_bound
,而且它们具有相同的理论复杂性。
答案 4 :(得分:-1)
如果要获取值的迭代器,可以使用std::equal_range,它将返回2个迭代器,一个位于下限,另一个位于值范围的上限,等于一个值你正在寻找。
由于唯一的要求是价值是排序的而不是唯一的,因此并不简单&#34;发现&#34;这会在你正在寻找的一个元素上返回一个迭代器。如果只有一个元素等于你要查找的值,则两个迭代器之间只有1的差异。