美文网首页
upper_bound 和lower_bound彻底搞懂

upper_bound 和lower_bound彻底搞懂

作者: 晓视君 | 来源:发表于2019-06-28 11:36 被阅读0次

    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. 引入数学半开半闭区间是很好的理解方式。

    相关文章

      网友评论

          本文标题:upper_bound 和lower_bound彻底搞懂

          本文链接:https://www.haomeiwen.com/subject/hlcscctx.html