和 需要用在一个有序数组或容器中,其复杂度均为 O(log(last - first))。
- 用来寻找在数组或容器的 范围内第一个值大于等于 val 的元素的位置,如果是数组,则返回该位置的指针;如果是容器,则返回该位置的迭代器。
- 用来寻找在数组或容器的 范围内第一个值大于 val 的元素的位置,如果是数组,则返回该位置的指针;如果是容器,则返回该位置的选代器。
显然,如果数组或容器中没有需要寻找的元素,则 和 均返回可以插入该元素的位置的指针或迭代器 (即假设存在该元素时,该元素应当在的位置)。
示例如下:
#include <stdio.h>
#include <algorithm>
using namespace std;
int main()
{
int a[10] = {1, 2, 2, 3, 3, 3, 5, 5, 5, 5}; //注意数组下标从0开始
//寻找-1
int* lowerPos = lower_bound(a, a + 10, -1);
int* upperPos = upper_bound(a, a + 10, -1);
printf("%d, %d\n", lowerPos - a, upperPos - a);
//寻找1
lowerPos = lower_bound(a, a + 10, 1);
upperPos = upper_bound(a, a + 10, 1);
printf("%d, %d\n", lowerPos - a, upperPos - a);
//寻找3
lowerPos = lower_bound(a, a + 10, 3);
upperPos = upper_bound(a, a + 10, 3);
printf("%d, %d\n", lowerPos - a, upperPos - a) ;
//寻找4
lowerPos = lower_bound(a, a + 10, 4);
upperPos = upper_bound(a, a + 10, 4);
printf("%d, %d\n", lowerPos - a, upperPos - a);
//寻找6
lowerPos = lower_bound(a, a + 10, 6);
upperPos = upper_bound(a, a + 10, 6);
printf("%d, %d\n", lowerPos - a, upperPos - a) ;
return 0;
}
输出结果:
显然,如果只是想获得欲查元素的下标,就可以不使用临时指针,而直接令返回值减去数组首地址即可:
#include <stdio.h>
#include <algorithm>
using namespace std;
int main()
{
int a[10] = {1, 2, 2, 3, 3, 3, 5, 5, 5, 5}; //注意数组下标从0开始
//寻找3
printf("%d, %d\n", lower_bound(a, a+10, 3) - a, upper_bound(a, a+10, 3) - a);
return 0;
}
输出结果:
【补充】
不得不说说前面的"有序序列",这里的"有序"是对什么有序?你可能已经猜到了,它是对于比较器有序,并且必须是升序!当然比较器默认也是"<
"。(为什么不是降序?这个你可能要去问问写STL的人)
一旦对降序序列使用lower_bound,就会出现神奇的错误,具体原因可以看这篇:点击这里
如果要在一个下降序列里寻找一个小于x的数呢?
所以,同样的,lower_bound和upper_bound也是可以加比较函数cmp的:
lower_bound(a+1, a+1+n, x, cmp);
bool cmp(const int& a, const int& b)
{
return a > b;
}
当然,你也可以这样:
lower_bound(a+1, a+1+n, x, greater<int>());
这里的greater<int>()
就是C++友情提供的方便的大于函数,这样就不用自己动手写一个cmp函数了 (其实就是懒)
【总结】
和 都是利用二分查找的方法在一个排好序的数组中进行查找的。
在从小到大的排序数组中,
-
:从数组的 位置到 位置二分查找第一个大于或等于 的数字,找到返回该数字的地址,不存在则返回 。通过返回的地址减去起始地址 ,得到找到数字在数组中的下标。
-
:从数组的 位置到 位置二分查找第一个大于 的数字,找到返回该数字的地址,不存在则返回 。通过返回的地址减去起始地址 ,得到找到数字在数组中的下标。
在从大到小的排序数组中,重载 和
-
:从数组的 位置到 位置二分查找第一个小于或等于 的数字,找到返回该数字的地址,不存在则返回 。通过返回的地址减去起始地址 ,得到找到数字在数组中的下标。
-
:从数组的 位置到 位置二分查找第一个小于 的数字,找到返回该数字的地址,不存在则返回 。通过返回的地址减去起始地址 ,得到找到数字在数组中的下标。