前言
此篇文章并非lower_bound()和upper_bound()的使用教学,是个人对于这两个方法的理解
如果你想学习方法的使用,可以参考下面这条博客:
C++ STL标准库std::set std::multiset 元素计数count() 查找元素find() lower_bound() upper_bound() equal_range()的使用
在我开始了解set库当中的lower_bound()和upper_bound()时,我也是搜索了别人的博客进行学习。我觉得很多人可能跟我一样,知道这两个方法是用于有序队列当中的,是返回>=参数val或>参数val的迭代器;
上面的认识并没有大问题,就是读者要注意,序列是从小到大排序时,从值的角度来说并没有问题,但是如果自己用在一个倒序的序列(greater<>或自写的比较器),再想获得>=某个val时(lower_bound(val)),序列中有相应的val值,你会得到那个值对应的iterator,但是序列中没有val值时,你得到的值是<val的iterator对象;
先给出我的理解:lower_bound()和upper_bound()的含义就如同,命名bound的含义一样,要以“界限”来理解这两个方法,而非val值的大小;
以lower_bound()方法,举个例子
一、set<int>小样例
#include <set>
#include <iostream>
using namespace std;
set<int> s;
//set<int, greater<int>> s;
int main() {
s.clear();
s.insert(1);
s.insert(3);
s.insert(5);
s.insert(7);
s.insert(9);
cout << *s.lower_bound(4) << endl;
}
5 //输出结果
倒序这个序列,注释掉set<int>,使用set<int, greater<int>> s;
3 //输出结果
二、图示理解:
- set<int>:
序列是升序时:可以假设一个元素(val=4)插入进来,以它当做界线,从set.begin()到“界线”为上界,从“界线”到set.end()为下界,如果set当中原来没有这个元素,lower_bound()则返回界线后面的一个元素的双向迭代器;所以lower_bound(4),返回的是指向5的迭代器; - set<int, greater<int>>
序列是降序时:同上,假设将val=4的元素insert进来,以它为界限;如果set当中原来没有这个值的元素,lower_bound(4)则返回“界线”后面的元素的双向迭代器,即返回指向元素3的迭代器;
upper_bound(),如果set中,“界线”无论能不能落到的set存在的元素上,都返回“界线”后面的元素的迭代器;
ps: 以降序为例子
// 遍历所有>=4的元素;
for(auto it = set.begin(); it != set.upper_bound(4); it++) { ... }
// 遍历所有>4的元素;
for(auto it = set.begin(); it != set.lower_bound(4); it++) { ... }
// 遍历所有<=4的元素;
for(auto it = set.lower_bound(4); it != set.end(); it++) { ... }
// 遍历所有<4的元素;
for(auto it = set.upper_bound(4); it != set.end(); it++) { ... }
总结
要用bound(界线)的含义来理解lower_bound()和upper_bound()