upper_bound 和lower_bound彻底搞懂

1.  问题引出

    今天在查看ORB_SLAM2注释版源码keyframe.cpp文件的时候,发现注释者的意见:


// http://www.cplusplus.com/reference/algorithm/upper_bound/

// 从mvOrderedWeights找出第一个大于w的那个迭代器

// 这里应该使用lower_bound,因为lower_bound是返回小于等于,而upper_bound只能返回第一个大于的


仔细对比发现并没有错,估计注释者并没有深刻理解这个上阙界和下阙界。对lower_bound和upper_bound翻译为这个数学术语是有原因的,同于数学中常用的范围域“ [  ) ”。

2. 彻底明白lower_bound和upper_bound

    小伙伴们可能从很多博客看到类似上述注释者这样的指导说明,但是往往让人难以理解,有点扰乱思路、抓狂。很简单的理解方法,数学中“a\in [  ) ”这串数学符号表示下界“[”小于等于a,上界“)”大于a,在数学中叫做“半开半闭”区间,即左闭右开。

    说列这么多,那如何和c++中的vector list等联系起来,把vector/llist的数据看成一条数轴,给定比较值的左边是lower_bound---"[",右边是upper_bound---")",这两个函数的使用要求vector/list等是排序好的,那是升序还是降序来着?默认情况是升序,降序需要指定。引入数学的理解,相信小伙伴们不会懵逼了,如果会,我也没办法。行上个代码增加一下理解。

3. 代码Code解释

3.1 升序情况

  代码来了:

#include<iostream>

#include<algorithm>

#include<vector>

#include<iterator>

using namespace std;

static bool weightComp( int a, int b)

    {

        return a>b;

    }

int main(int argc,char**argv)

{

    std::vector<int> vecInt;

    vecInt.push_back(1);

    vecInt.push_back(3);

    vecInt.push_back(19);

    vecInt.push_back(2);

    vecInt.push_back(4);

    vecInt.push_back(7);

    std::sort(vecInt.begin(),vecInt.end());

    for(auto itt:vecInt)

    {

        std::cout<<itt<<endl;

    }

    std::vector<int>::iterator it=lower_bound(vecInt.begin(),vecInt.end(),4);

    std::cout<<"lower bound: "<<*it<<endl;

    it=upper_bound(vecInt.begin(),vecInt.end(),4);

    std::cout<<"upper bound: "<<*it<<endl;

    return 0;

}

输出:

3.2 降序情况

    降序情况一定要记得指定比较函数

#include<iostream>

#include<algorithm>

#include<vector>

#include<iterator>

using namespace std;

static bool weightComp( int a, int b)//指定比较函数,重要事情说3遍

    {

        return a>b;

    }

int main(int argc,char**argv)

{

    std::vector<int> vecInt;

    vecInt.push_back(1);

    vecInt.push_back(3);

    vecInt.push_back(19);

    vecInt.push_back(2);

    vecInt.push_back(4);

    vecInt.push_back(7);

    std::sort(vecInt.begin(),vecInt.end(),weightComp);//指定比较函数,重要事情说3遍

    for(auto itt:vecInt)

    {

        std::cout<<itt<<endl;

    }

    std::vector<int>::iterator it=lower_bound(vecInt.begin(),vecInt.end(),4,weightComp);//指定比较函数,重要事情说3遍

    std::cout<<"lower bound: "<<*it<<endl;

    it=upper_bound(vecInt.begin(),vecInt.end(),4,weightComp);//指定比较函数,重要事情说3遍

    std::cout<<"upper bound: "<<*it<<endl;

    return 0;

}

输出:

    好了,到了这里小伙伴还有什么不明白的吗?可以联系@我。在次总结一下,a. 使用这两个函数前vector/list等要排序; b. 调用函数时默认是升序,降序记得指定并自己编写比较函数. c. 引入数学半开半闭区间是很好的理解方式。

  • 9
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jeff_ROS

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值