upper_bound和lower_bound

文章介绍了C++标准库中的头文件中的lower_bound和upper_bound函数,用于在有序数组或容器中查找元素。这两个函数分别返回大于等于和大于给定值的第一个元素的地址,适用于数组和vector。文章强调了使用前需保证数据有序,并提到了在不同容器中的时间复杂度差异,还展示了如何进行降序查找和自定义比较函数的例子。
摘要由CSDN通过智能技术生成

头文件:<algorithm>

功能:扩展版二分查找(upper_bound查找第一个大于给定数的元素地址,lower_bound查找第一个大于等于给定数的元素地址)

条件:数组必须有序

返回值:返回目标的地址,可以减去查找起始地址得到下标,查找失败返回查找范围长度,查找成功返回下标

基础使用

int nums[n];

//返回nums中第一个大于等于aim的元素地址,若不存在则返回nums[n+1]地址
第一个参数查找左边界地址(包括)
第二个参数查找右边界地址(不包括)
第三个参数aim查找元素
int *num = lower_bound(nums,nums+n,aim); 

//返回nums中第一个大于等于aim的元素下标
int pos = lower_bound(nums,nums+n,aim) - nums;

upper_bound用法也是这样,只不过是返回大于aim的元素地址
int *num = upper_bound(nums,nums+n,aim);
int pos = upper_bound(nums,nums+n,aim);

vector容器也可以使用该方法
vector<int>nums;
int pos = upper_bound(nums.begin(),nums.end(),aim) - nums.begin();

注意点

1.使用lower_bound和upper_bound前必须保证数组有序,可以先使用sort排序。

2.在一般数组中(定义数组以及vector中)这两个函数的时间复杂度均为log(n),但是在set等关联式容器中直接使用这两个函数的时间复杂度为O(n^2),只有使用set等关联式容器中封装的upper_bound和lower_bound时间复杂度才可以达到O(log(n))。

set<int>s;

s.lower_bound(3);//在集合s中查找第一个大于等于3的元素。注意 这里就不是元素地址了

进阶使用

1.查找第一个小于等于指定元素的元素下标

int nums[n];

//使用sort降序
sort(num,num+n,greater<int>());  //这里的greater<int>()含义指的是上一个元素比下一个元素大

//lower_bound 查找小于等于aim的元素下标
int pos = lower_bound(num,num+n,aim,greater<int>()) - num;

2.查找第一个小于指定元素的元素下标

int nums[n];

//使用sort降序
sort(num,num+n,greater<int>());  //这里的greater<int>()含义指的是上一个元素比下一个元素大

//upper_bound 查找小于等于aim的元素下标
int pos = upper_bound(num,num+n,aim,greater<int>()) - num;

3.自定义查找规则

struct Point
{
    int x, y;
    Point(int x,int y)
    {
        this->x = x;
        this->y = y;
    }
};
//比较函数
bool cmp(Point a, Point b)
{
    if(a.x != b.x) //按第一个元素降序排序,若第一个元素相等再按照第二个元素降序排列
        return a.x > b.x;
    return a.y > b.y;
}


Point a[4] = {Point(0,1),Point(1,3),Point(1,2),Point(2,3)};
sort(a,a+4,cmp);
for(int i = 0; i < 4; i++)
{
     cout<<a[i].x<<" "<<a[i].y<<endl;
}
cout<<endl;
int pos = upper_bound(a,a+4,Point(2,2),cmp) - a;
cout<<a[pos].x<<" "<<a[pos].y<<endl;

/*
2 3
1 3
1 2
0 1

1 3

*/

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值