C++ STL的查找算法

假設你有一個序列容器,或者有一對迭代器標識了一個區間,現在你希望在容器中查找一些信息,這樣的查找工作如何進行呢?你的選擇往往是:
count,count_if,find,find_if,binary_search,lower_bound,upper_bound,equal_range.該如何選擇呢?
現在,我們假設你有了一對迭代器,他們指定了一個被選擇的區間。
在選擇具體的策略時,需要考慮由迭代器指定的區間是否是排序的,這是一個至關重要的決定條件。

未排序區間

如果迭代器并沒有指定一個排序的區間,那么你的選擇是count/count_if,find/find_if.這些算法提供線性時間的效率。

count

問題:
區間中是否有某個特定的值?如果有,有幾個?
用法:

list<Widget> lw;
Widget w;
...
if(count(lw.begin(),lw.end(),w)!=0)//w在lw中
{
....
}
else//w不在lw中
{
.....
}

這段代碼演示了一種常見的習慣用法:將count用在存在性測試。count返回0或者一個正整數

find

問題:
區間中是否有某個特定的值?如果有,在哪里?
用法:

if(find(lw.begin(),lw.end(),w)!=lw.end())//存在w
{
...
}
else//不存在w
{
...
}

從存在性測試的角度來看,count的習慣用法較為容易編碼一些,但同時,他的效率要差一些。因為find一旦找到第一個匹配的結果后馬上返回,而count必須到達區間的末尾,以便找到所有的匹配。

排序區間

對于已經排序的區間,我們將使用binary_search、lower_bound、upper_bound、equal_range.它們以對數時間運行。其實他們的背后是二分查找法。

binary_search

問題:
binary_search僅僅返回的是一個bool值:是否找到了特定的值
用法:

vector<Widget> vw;
...
sort(vw.begin(),vw.end());
Widget w;
...
if(binary_search(vw.begin(),vw.end(),w))
{
...//w在vw中
}
else
{
...//w不在vw中
}

lower_bound

問題:
這個值在區間中嗎?如果在,那么第一個拷貝在哪里?如果不在,他該往哪里插入?
用法
我們僅將lower_bound用在下面的情景中
假設我們有一個Timestamp類和一個存放Timestamp的vector,并且這個vector已經排過序,其中老的時間排在前面。

class Timestamp{...};
bool operator<(const Timestamp& lhs,const Timestamp& rhs);//判斷lhs是否在rhs之前
vector<Timestamp> vt;
...
sort(vt.begin(),vt.end());

現在假設有一個特殊的時間戳,ageLimit,我們希望刪除所有在ageLimit之前的Timestamp對象。在這種情況下,我們并不想找到
該區間中與ageLimit等價的Timestamp類,因為該區間中可能根本沒有與它等價的對象。我們其實想在vt中找到一個位置:第一個不比ageLimit老的位置。這是非常容易的,因為lower_bound給我們一個準確地答案:

Timestamp ageLimit;
...
vt.erase(vt.begin(),lower_bound(vt.begin(),vt.end(),ageLimit));//刪除所有在ageLimit之前的對象

那么如果我們想刪除那些至少和ageLimit一些老的對象呢?
這就是我們即將看到的upper_bound

upper_bound

問題:
這個值在區間中嗎?如果在,那么最后一個拷貝的下一個位置在哪里?如果不在,他該往哪里插入?
用法
同樣我們也只考慮以上給出的應用,
代碼如下:

vt.erase(vt.begin(),upper_bound(vt.begin(),vt.end(),ageLimit));//從vt中刪除所有在ageLimit之前或者與ageLimit等價的對象

我們看到lower_bound與upper_bound的用法與給出的問題,似乎有點不合,實際上,我在這里做了簡化,只列出了使用以上兩個函數的最常見和最應該使用之處,至于其它,建議參考《Effective STL》45條

equal_range

問題:
這個值在區間中嗎?如果在,在哪里?
用法

vector<Widget> vw;
...
sort(vw.begin(),vw.end());
typedef vector<Widget>::iterator VWIter;
typedef pair<VWIter,VWIter> VWIterPair;
VWIterPair p=eauql_range(vw.begin(),vw.end(),w);
if(p.first!=p.second)//如果equal_range返回非空區間,
{                   //找到了特定值,p.first指向第一個與w等價的
...                 //對象,p.second指向最后一個與w等價的對象                    
}                   //的下一個位置
else
{
...                   //沒有找到特定值,p.first與p.second都       
}                     //指向w的插入位置

而且,你還可以打印出有多少個這樣的對象。

VWIterPair p=eauql_range(vw.begin(),vw.end(),w);
cout<<"There are"<<distance(p.first,p.second)<<"elements in vw equivalent to w.";

注意:
以上我們的方法使用與序列容器如:vector,string,deque,list。
關聯容器也有count.find,equal_range,lower_bound,upper_bound成員函數。凡是前面的討論中建議選擇以上算法的,在關聯容器中只要使用同名的成員函數即可。只有binary_search例外,因為關聯容器中沒有這個成員函數。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/259211.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/259211.shtml
英文地址,請注明出處:http://en.pswp.cn/news/259211.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

習題七

umask 022 &#xff0c;請描述該命令的含義創建目錄時默認的權限為&#xff1a;755 rwxr-xr-x創建文件時默認的權限為&#xff1a;644 rw-r--r--note:創建文件的默認權限是拿掉了X 所以最大為666&#xff0c;而目錄最大為777 umask NUM 就是去掉相應的權限轉載于:https://blo…

web中的cookie管理

本篇是以JSP為背景介紹&#xff0c;但是在web開發中也是相同的原理。 什么是cookie 由于http是一種無狀態的協議&#xff0c;因此服務器收到請求后&#xff0c;只會當做一次新的請求。即便你重復發送了1000次同樣的請求&#xff0c;這1000次都屬于獨立的請求。 這樣顯然效率很低…

unity怎么設置游戲頁面_杭州有沒有正規的unity游戲開發培訓機構?

現在Unity游戲開發是個火熱的行業&#xff0c;薪資待遇比較高&#xff0c;未來的發展方向和前景也比較不錯&#xff0c;很多人也都想成為專業Unity游戲開發工程師&#xff0c;學習Unity游戲開發已經成為很多追求更好就業前景的人的選擇。學習專業、系統的Unity游戲開發知識并達…

VC++ 使用attributes定義接口

1.定義預處理命令_ATL_ATTRIBUTES 2.在一個全局的Cpp文件里面配置module的attribute [module(dll, uuid "{3845951F-15B8-4286-8E7D-E9D4F5C7B6CE}", name "TestApp")]3.定義接口 [object,uuid("9F414A8A-1D5E-4aff-A60E-CFD65155ABB6"),dual,…

h3c 虛擬服務器 下一跳,H3CNE 312題和313題 直連路由靜態路由的下一跳問題

321.在MSR 路由器上看到路由表里有如下顯示&#xff1a; Destination/Mask Proto Pre Cost NextHop Interface 127.0.0.0/8 Direct 0 0 127.0.0.1 InLoop0 127.0.0.1/32 Direct 0 0 127.0.0.1 InLoop0 192.168.96.0/19 Direct 0 0 192.168.120.153 S6/0 那么關于目的地321.在MS…

C++成員變量的初始化順序問題

先來看兩道題&#xff1a; // count algorithm example #include <iostream> // std::cout #include <algorithm> // std::count #include <vector> // std::vector using namespace std; class A { public:A() { cout << "in A()&q…

Knockout.Js案例一Introduction

在這第一個教程中,您將體驗的一些基本知識構建的web UI Model-View-ViewModel使用knockout.js(MVVM)模式。案例1&#xff1a;添加:data-bind <p>First name: <strong data-bind"text:firstName">1</strong></p><p>Last name: <stro…

C#注冊表常用操作

1&#xff1a;加鍵 改值 Microsoft.Win32.RegistryKey Key Microsoft.Win32.Registry.CurrentUser.CreateSubKey( "Software\Microsoft\Internet Explorer\Main"); Key.SetValue( "Window Title" , value ); Key.Close(); …

谷歌瀏覽器外貿版_做外貿快兩個月,沒有單怎么辦?

Hello 大家好&#xff0c;我是Jack。今天給大家更新一篇在知乎看到的外貿問題&#xff1a;做外貿快兩個月&#xff0c;沒有單怎么辦?外貿這個話題在知乎算是小眾話題了&#xff0c;相比較于職場&#xff0c;英語學習&#xff0c;國際政治&#xff0c;IT等&#xff0c;這些話題…

React Native通信機制詳解

http://blog.cnbang.net/tech/2698/ React Native是facebook剛開源的框架&#xff0c;可以用javascript直接開發原生APP&#xff0c;先不說這個框架后續是否能得到大眾認可&#xff0c;單從源碼來說&#xff0c;這個框架源碼里有非常多的設計思想和實現方式值得學習&#xff0c…

C++11系列學習之四----auto

在哪些情況下要申明類型&#xff1a; 定義變量類型 函數返回值&#xff0c;函數參數 表達式返回變量類型 auto關鍵字原理 在定義變量的時候必須申明類型&#xff0c;c是強語言類型&#xff0c;在編譯階段需要知道類型&#xff0c;這樣的好處是程序效率更高&#xff0c;而…

windows 自動copy遠程服務器文件

net use h: \\123.45.67.000\T1dbbackup 123456/user:administrator ------遠程服務器IP123.45.67.000 。T1dbbackup&#xff1a;共享文件夾 。 h :映射到本機的盤符。 用戶名&#xff1a;administrator&#xff0c;密碼&#xff1a;123456copy h:\*.* f:\T1DB ------復…

eclipse 不能切換輸入法

按了AltShift鍵&#xff1f;再按一次把EN切換成CN&#xff0c;然后再CtrlShift就可以切換輸入法轉載于:https://www.cnblogs.com/jiayonghua/p/3413827.html

excel打開2個獨立窗口_謝楠稱女性獨立的不是錢是心 謝楠與吳京婚后生育2個兒子...

近日&#xff0c;在綜藝節目《幸福三重奏》 三日談妻子篇中&#xff0c;謝楠被問到如何看待獨立女性時&#xff0c;反問記者會不會問吳京同樣的問題&#xff1b;隨后回答道&#xff0c;女性獨立的不是錢&#xff0c;而是你的心&#xff1b;楠姐的回答超級霸氣了&#xff0c;你們…

C++11系列學習之五-------decltype

使用場景 在C中經常要用到很長的變量名&#xff0c;如果已經有變量和你將使用的變量是一個類型&#xff0c;即可使用decltype關鍵字 來申明一樣的類型變量。 decltype原理 返回現有變量類型&#xff0c;decltype是一個關鍵字&#xff0c;而不是一個函數&#xff0c;這有啥區別…

Linux學習 Unit 9

Unit9.openssh-server1.openssh-server功能&#xff1a;讓遠程主機可以通過網絡訪問sshd服務&#xff0c;開始一個安全shell2.客戶端連接方式ssh遠程主機用戶遠程主機ip[rootdesktop0 ~]# ssh root172.25.0.11The authenticity of host 172.25.0.11 (172.25.0.11) cant be esta…

2015年創業中遇到的技術問題:41-50

41.Bootstrap換行。col-md-10和col-md-2。這2個div按說應該在一行的&#xff0c;結果col-md-2換行了。看看樣式&#xff0c;發現有多余的“margin-left: 1px;"。42.Service實現類定義了一個“自動調度進行刷新”的方法。OverrideScheduled(cron "0 0/10 * * * ? &q…

KMP模板與講解

讀書筆記終于寫完了&#xff0c;寫一下我對KMP的理解。 KMP的思想就是盡量利用已經得到的信息&#xff0c;來降低時間復雜度&#xff0c;已經得到的信息存放在next數組里。算法確實很難理解&#xff0c;所以很難講解。。舉個例子來說吧。 設字符串是str[]&#xff0c;next[5] …

android 非root app 捕捉系統廣播_APP的生死之道

這篇文章主要介紹APP在安卓系統中是怎么被殺死的&#xff0c;按照怎樣的一個策略去釋放進程&#xff1b;同時介紹一些延長應用存活時間的方案&#xff0c;雖然這個在現在安卓系統上越來越難實現了&#xff0c;但是也是可以稍微了解下&#xff0c;主要也是通過這些hack的方案更好…

C++11系列學習之六-----for

前言C11這次的更新帶來了令很多C程序員期待已久的for range循環&#xff0c;每次看到javascript&#xff0c; lua里的for range&#xff0c;心想要是C能有多好&#xff0c;心里別提多酸了。這次C11不負眾望&#xff0c;再也不用羨慕別家人的for range了。使用場景ex1&#xff1…