为什么std :: binary_search返回bool?

时间:2015-05-28 01:27:50

标签: c++ c++11 stl-algorithm

根据草稿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)比较。

有谁知道为什么会这样?

大多数其他泛型算法要么将迭代器返回到元素,要么迭代器等效于表示元素序列末尾的迭代器(即,序列中要考虑的最后一个元素之后的迭代器),这是什么我原以为是。

5 个答案:

答案 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_boundupper_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_boundupper_boundequal_range函数来检索迭代器。

答案 3 :(得分:0)

标准库包含返回迭代器的二进制搜索算法的变体。它们被称为std::lower_boundstd::upper_bound。我认为std::binary_search返回bool背后的基本原理是,在等效元素的情况下,它不会清楚返回的迭代器,而在std::lower_boundstd::upper_bound的情况下,它很清楚

也可能存在性能因素,因为理论上std::binary_search可以实现在多个等效元素和某些类型的情况下更好地执行。但是,标准库(libstdc++)的至少一个流行实现使用std::binary_search实现std::lower_bound,而且它们具有相同的理论复杂性。

答案 4 :(得分:-1)

如果要获取值的迭代器,可以使用std::equal_range,它将返回2个迭代器,一个位于下限,另一个位于值范围的上限,等于一个值你正在寻找。

由于唯一的要求是价值是排序的而不是唯一的,因此并不简单&#34;发现&#34;这会在你正在寻找的一个元素上返回一个迭代器。如果只有一个元素等于你要查找的值,则两个迭代器之间只有1的差异。