简体   繁体   English

C++ 中的lower_bound()

[英]lower_bound() in C++

From reading from the Internet, I understand that The lower_bound() method in C++ is used to return an iterator pointing to the first element in the range [first, last) which has a value not less than value.从网上看,我了解到C++中的lower_bound()方法是用来返回一个迭代器,该迭代器指向范围[first, last)中第一个值不小于value的元素。 This means that the function returns the index of the next smallest number just greater than that number.这意味着该函数返回下一个刚好大于该数字的最小数字的索引。

So, for the given code below I understood that the output is 3. But, as there is repetition of 6. How can I get the index of last 6 using lower_bound() .所以,对于下面给定的代码,我理解输出是 3。但是,因为有 6 的重复。如何使用lower_bound()获得最后 6 的索引。 I can implement my own binary_search() for that, but I want to know how to do it by lower_bound() .我可以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; 
} 

Use pair of lower_bound and upper_bound .使用对lower_boundupper_bound Or one equal_range -- that would be more optimal.或者一个equal_range那会更理想。

Both upper_bound and high part of equal_range would be past the last "6". equal_range upper_bound和 high 部分都将超过最后一个“6”。 The same as end is not last, it is past the last.就像结束不是最后一样,它已经过去了最后。

You can use reverse iterators into the vector, but then to fulfill the ordering requirement for std::lower_bound you need to inverse the comparison, so you need to use std::greater instead of the default std::less .您可以在向量中使用反向迭代器,但是为了满足std::lower_bound的排序要求,您需要反转比较,因此您需要使用std::greater而不是默认的std::less This however also means that now you are not really looking for a lower bound, but for an upper bound with respect to that comparison function, so:然而,这也意味着现在您并不是真正在寻找下限,而是在寻找与该比较函数相关的上限,因此:

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

If the array is sorted, iterating between lower_bound and upper_bound you get all elements which equal your pivot point:如果数组已排序,则在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);
}

The question you are asking, ie what is the index of the last 6 , doesn't have a corresponding function in the standard library because is ill-defined in the case when the range doesn't contain any 6 .您问的问题,即最后6的索引是什么,在标准库中没有相应的函数,因为在范围不包含任何6的情况下定义不明确。 In all other cases since you have a random access container you can get an iterator to the last 6 by removing one from upper_bound ( upper - 1 in your code), in the same way you get the last index of an array by removing 1 from length.在所有其他情况下,由于您有一个随机访问容器,您可以通过从upper_bound删除一个来获得最后6个迭代器(在代码中为upper - 1 ),就像通过从长度。 However I suggest you avoid relying on the position of the last element equal when you design your algorithm.但是,我建议您在设计算法时避免依赖最后一个元素的位置相等。 Also note that if you need both lower and upper bound you can get both at the same time with equal_range , which may even perform better because it may be optimised to only traverse the data structure once:另请注意,如果您同时需要下限和上限,您可以使用equal_range同时获得两者,这甚至可能性能更好,因为它可能被优化为仅遍历数据结构一次:

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

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

You can use lower_bound again, updating the begin and the value:您可以再次使用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