【STL】 lower_bound和upper_bound
在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(logN)
实验代码如下:
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;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!