C++ 中的 lower_bound()

Posted

技术标签:

【中文标题】C++ 中的 lower_bound()【英文标题】:lower_bound() in C++ 【发布时间】:2020-03-23 17:11:13 【问题描述】:

从网上了解到,C++ 中的lower_bound() 方法用于返回一个迭代器,该迭代器指向[first, last) 范围内的第一个元素,其值不小于value。这意味着该函数返回比该数字大的下一个最小数字的索引。

所以,对于下面给定的代码,我知道输出是 3。但是,由于重复 6。如何使用 lower_bound() 获取最后 6 个的索引。我可以为此实现自己的binary_search(),但我想知道如何通过lower_bound() 来实现。

#include <iostream> 
#include <algorithm>
#include <vector> 

using namespace std; 

int main () 
 
    int array[] = 5,6,7,7,6,5,5,6; 

    vector<int> v(array,array+8); // 5 6 7 7 6 5 5 6 

    sort (v.begin(), v.end()); // 5 5 5 6 6 6 7 7 

    vector<int>::iterator lower,upper; 
    lower = lower_bound (v.begin(), v.end(), 6); 
    upper = upper_bound (v.begin(), v.end(), 6); 

    cout << "lower_bound for 6 at position " << (lower- v.begin()) << '\n'; 
    return 0; 
 

【问题讨论】:

实际上不,要搜索的元素的最后一个索引,例如在给定的代码中,我正在寻找的输出是 5。因为要搜索的元素是 6。 听起来你想要你已经在使用的upper_bound。也许您需要一个更好的问题来准确显示您想要的输出 auto lower_plus_one = lower_bound (v.begin(), v.end(), 6+1); 然后lowerlower_plus_one 是6的范围。 真的需要lower_bound而不是upper_bound吗? @aschepler 这不是必需品。 【参考方案1】:

使用一对lower_boundupper_bound。或者一个equal_range——那会更理想。

upper_boundequal_range 的高位部分将是过去最后一个“6”。同end不是最后一个,是过去最后一个。

【讨论】:

我还是没明白。【参考方案2】:

您可以在向量中使用反向迭代器,但是为了满足std::lower_bound 的排序要求,您需要反转比较,因此您需要使用std::greater 而不是默认的std::less。然而,这也意味着现在您并不是真的在寻找下限,而是在寻找与该比较函数相关的上限,所以:

auto upper = std::upper_bound(v.rbegin(), v.rend(), 6, std::greater);

【讨论】:

【参考方案3】:

如果数组已排序,则在 lower_boundupper_bound 之间进行迭代,您将获得与您的轴心点相等的所有元素:

lower = lower_bound(v.begin(), v.end(), 6);
upper = upper_bound(v.begin(), v.end(), 6);

for (auto it = lower; it != upper; it++) 
    assert(6 == *it);

您要问的问题,即最后一个6 的索引是什么,在标准库中没有相应的函数,因为在范围不包含任何@987654325 的情况下定义不明确@。在所有其他情况下,由于您有一个随机访问容器,您可以通过从 upper_bound(代码中的 upper - 1)中删除一个迭代器来获得最后一个 6 的迭代器,就像您获得数组的最后一个索引一样通过从长度中删除 1。 但是,我建议您在设计算法时避免依赖最后一个元素的位置相等。另请注意,如果您需要下限和上限,您可以使用equal_range 同时获得两者,这甚至可能会表现得更好,因为它可能会被优化为只遍历数据结构一次:

std::tie(lower,upper) = equal_range(v.begin(), v.end(), 6);

for (auto it = lower; it != upper; it++) 
    assert(6 == *it);

【讨论】:

【参考方案4】:

您可以再次使用lower_bound,更新开始和值:

auto lower = std::lower_bound (v.cbegin(), v.cend(), 6); 
auto upper = std::lower_bound (lower, v.cend(), 6 + 1);

std::cout << "Number of values found: " << std::distance(lower, upper) << '\n'; 

【讨论】:

以上是关于C++ 中的 lower_bound()的主要内容,如果未能解决你的问题,请参考以下文章

为啥 C++ lower_bound() 允许返回与 val 等效的指针,而 upper_bound() 不允许

c++ stl 中 lower_bound 的第四个参数的用法

c++中 map里upper_bound和lower_bound分别怎么理解啊? 主要是想问关键字的上界和下界是啥意思。

stl map中的lower_bound和 upper_bound

如何在向量向量上使用lower_bound?

lower_bound()函数与quicksort()函数的简单掌握