繁体   English   中英

C++ 中的lower_bound()

[英]lower_bound() in C++

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

所以,对于下面给定的代码,我理解输出是 3。但是,因为有 6 的重复。如何使用lower_bound()获得最后 6 的索引。 我可以binary_search()实现我自己的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; 
} 

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

equal_range upper_bound和 high 部分都将超过最后一个“6”。 就像结束不是最后一样,它已经过去了最后。

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

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

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

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

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

您可以再次使用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'; 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM