upper_bound 和lower_bound徹底搞懂

1.? 問題引出

? ? 今天在查看ORB_SLAM2注釋版源碼keyframe.cpp文件的時(shí)候,發(fā)現(xiàn)注釋者的意見:


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

// 從mvOrderedWeights找出第一個(gè)大于w的那個(gè)迭代器

// 這里應(yīng)該使用lower_bound,因?yàn)閘ower_bound是返回小于等于,而upper_bound只能返回第一個(gè)大于的


仔細(xì)對(duì)比發(fā)現(xiàn)并沒有錯(cuò),估計(jì)注釋者并沒有深刻理解這個(gè)上闕界和下闕界。對(duì)lower_bound和upper_bound翻譯為這個(gè)數(shù)學(xué)術(shù)語是有原因的,同于數(shù)學(xué)中常用的范圍域“ [? ) ”。

2. 徹底明白lower_bound和upper_bound

????小伙伴們可能從很多博客看到類似上述注釋者這樣的指導(dǎo)說明,但是往往讓人難以理解,有點(diǎn)擾亂思路、抓狂。很簡(jiǎn)單的理解方法,數(shù)學(xué)中“a\in [? ) ”這串?dāng)?shù)學(xué)符號(hào)表示下界“[”小于等于a,上界“)”大于a,在數(shù)學(xué)中叫做“半開半閉”區(qū)間,即左閉右開。

? ? 說列這么多,那如何和c++中的vector list等聯(lián)系起來,把vector/llist的數(shù)據(jù)看成一條數(shù)軸,給定比較值的左邊是lower_bound---"[",右邊是upper_bound---")",這兩個(gè)函數(shù)的使用要求vector/list等是排序好的,那是升序還是降序來著?默認(rèn)情況是升序,降序需要指定。引入數(shù)學(xué)的理解,相信小伙伴們不會(huì)懵逼了,如果會(huì),我也沒辦法。行上個(gè)代碼增加一下理解。

3. 代碼Code解釋

3.1 升序情況

????簡(jiǎn)書不好插入代碼,吐槽一下,誰知道可以告訴我。

#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 降序情況

? ? 降序情況一定要記得指定比較函數(shù)

#include<iostream>

#include<algorithm>

#include<vector>

#include<iterator>

using namespace std;

static bool weightComp( int a, int b)//指定比較函數(shù),重要事情說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);//指定比較函數(shù),重要事情說3遍

? ? for(auto itt:vecInt)

? ? {

? ? ? ? std::cout<<itt<<endl;

? ? }

? ? std::vector<int>::iterator it=lower_bound(vecInt.begin(),vecInt.end(),4,weightComp);//指定比較函數(shù),重要事情說3遍

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

? ? it=upper_bound(vecInt.begin(),vecInt.end(),4,weightComp);//指定比較函數(shù),重要事情說3遍

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

? ? return 0;

}

輸出:

????好了,到了這里小伙伴還有什么不明白的嗎?可以聯(lián)系@我。在次總結(jié)一下,a. 使用這兩個(gè)函數(shù)前vector/list等要排序; b. 調(diào)用函數(shù)時(shí)默認(rèn)是升序,降序記得指定并自己編寫比較函數(shù). c. 引入數(shù)學(xué)半開半閉區(qū)間是很好的理解方式。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容