在STL提供的 algorithm
头文件中,提供了两个函数:upper_bound
和 lower_bound
,这俩函数功能 ”类似“,但并不相同。
- lower_bound(begin,end,val)在有序的数组连续地址的[begin,end)内找到第一个位置并返回其地址,使得val插入这个位置前面,数组仍然保持有序
- upper_bound(begin,end,val)在有序的数组连续地址的[begin,end)内找到最后个位置并返回其地址,使得val插入这个位置前面,数组仍然保持有序
即:lower_bound函数可以返回某数第一次出现的位置,upper_bound可以返回某数最后一次出现的位置(的后面)
因为返回的是地址,那么减去arr.begin()即可得到下标。
其原理都是二分,时间复杂度O(NlogN)
实验代码如下:
int test[6] = {1,2,3,3,6,8};
cout << lower_bound(test,test+6,3) - test << endl;
cout << upper_bound(test,test+6,3) - test << endl;
输出为2 4
如果查找数组元素不存在与数组中呢,那么根据二分查找的原理,有三种结果
- 如果查找元素tar小于有序数组的第一个元素,那么返回数组第一个下标
- 如果查找元素tar大于有序数组的最后一个元素,那么返回数组最后一个下标
- 如果查找元素不存在但也不满足1,2,那么返回数组内第一个大于tar的数组元素下标
实验代码如下:
int test[6] = {1,2,3,3,6,8};
cout << lower_bound(test,test+6,4) - test << endl;
cout << upper_bound(test,test+6,4) - test << endl;
输出为:4 4(6的下标)
在从大到小的排序数组中,重载lower_bound()和upper_bound()
lower_bound( begin,end,num,greater<type>() ):从数组的begin位置到end-1位置二分查找第一个小于或等于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
upper_bound( begin,end,num,greater<type>() ):从数组的begin位置到end-1位置二分查找第一个小于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
用二分查找实现lower_bound和upper_bound的函数实现如下
int lowerBound (int arr[],int l,int r,int tar) {
while (l<r) {
int mid = (l + r) >> 1;
if (test[mid] < tar) l=mid+1;
else r=mid;
}
return l;
}
int upperBound (int arr[],int l,int r,int tar) {
while (l<r) {
int mid = (l + r) >> 1;
if (test[mid] <= tar) l=mid+1;
else r=mid;
}
return l;
}
标签:upper,begin,end,STL,bound,int,数组 From: https://www.cnblogs.com/Yukie/p/17922701.html