使用lower_bound函数进行二进制搜索

时间:2015-05-22 12:09:53

标签: c++ algorithm

我正在使用lower_bound函数,以便返回迭代器而不是布尔值。

auto testPair = make_pair(0, 0);
auto it3 = std::lower_bound(vec[1].begin(), vec[1].end(), testPair, [](const std::pair<int, double> a, const std::pair<int, double> b)
{
    return a.first < b.first;
});
if (it3 != vec[1].end() && !(testPair.first < it3->first))
    vec[1].erase(it3);

我基本上采用了原始实现并对其进行了更改,以便它返回一个迭代器,以便我可以使用对。

我的问题在以下一行:

if (it3 != vec[1].end() && !(testPair.first < it3->first))

我的感觉是可以删除第二个逻辑语句,因为通过使用lower_bound,它应该意味着testPair.first永远不应该大于it3-&gt;。但是,如果删除if语句的那部分,它在某些情况下无法正常工作。

有没有人能够了解这是为什么以及为什么需要它?

如果我通过一对

    auto testPair = make_pair(0, 0);

成对的矢量,其中包含以下

std::push_back(std::make_pair(1,1.6));
std::push_back(std::make_pair(2,1.7));

当它不应删除任何第二对时,它将删除第二对。

1 个答案:

答案 0 :(得分:2)

算法std::lower_bound返回迭代器,在此之前可以在序列中插入目标值,使序列仍然有序。这并不意味着算法总是返回指向具有相同目标值的元素的迭代器。

例如,如果你有一个像

这样的序列
{ 0, 2, 4, 6 }

并将算法用于值3,然后它将返回指向4的迭代器。序列没有值为3的元素。 因此,您应该检查自己迭代器是否指向具有相同值的元素。

对于类型为int的对象,您可以简单地编写

if ( it3 != vec[1].end() && testPair.first == it3->first )
                                           ^^^

但总的来说(例如,当使用浮点数时)最好使用运算符&lt;因为它是这个运算符通常用于排序序列。例如,不需要在类中声明operator ==来通过运算符&lt;来对类的一系列对象进行排序。然后使用算法std :: lower_bound来查找目标元素

实际上对于你的代码片段这句话

if (it3 != vec[1].end() && !(testPair.first < it3->first))

等同于上述陈述。 testPair.first不能大于it3->first。同时,如果它不小于it3->first,那么你可以得出结论它们是平等的。