C STL的查詢演算法

2021-07-05 04:07:57 字數 3242 閱讀 1213

假設你有乙個序列容器,或者有一對迭代器標識了乙個區間,現在你希望在容器中查詢一些資訊,這樣的查詢工作如何進行呢?你的選擇往往是:

count,count_if,find,find_if,binary_search,lower_bound,upper_bound,equal_range.該如何選擇呢?

現在,我們假設你有了一對迭代器,他們指定了乙個被選擇的區間。

在選擇具體的策略時,需要考慮由迭代器指定的區間是否是排序的,這是乙個至關重要的決定條件。

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

問題:

區間中是否有某個特定的值?如果有,有幾個?

用法:

list

lw;widget w;

...if(count(lw.begin(),lw.end(),w)!=0)//w在lw中

else

//w不在lw中

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

問題:

區間中是否有某個特定的值?如果有,在**?

用法:

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僅僅返回的是乙個bool值:是否找到了特定的值

用法:

vectorvw;

...sort(vw.begin(),vw.end());

widget w;

...if(binary_search(vw.begin(),vw.end(),w))

else

問題:

這個值在區間中嗎?如果在,那麼第乙個拷貝在**?如果不在,他該往**插入?

用法

我們僅將lower_bound用在下面的情景中

假設我們有乙個timestamp類和乙個存放timestamp的vector,並且這個vector已經排過序,其中老的時間排在前面。

class timestamp;

bool operator<(const timestamp& lhs,const timestamp& rhs);//判斷lhs是否在rhs之前

vectorvt;

...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

問題:

這個值在區間中嗎?如果在,那麼最後乙個拷貝的下乙個位置在**?如果不在,他該往**插入?

用法

同樣我們也只考慮以上給出的應用,

**如下:

vt.erase(vt.begin(),upper_bound(vt.begin(),vt.end(),agelimit));//從vt中刪除所有在agelimit之前或者與agelimit等價的物件
我們看到lower_bound與upper_bound的用法與給出的問題,似乎有點不合,實際上,我在這裡做了簡化,只列出了使用以上兩個函式的最常見和最應該使用之處,至於其它,建議參考《effective stl》45條

問題:

這個值在區間中嗎?如果在,在**?

用法

vectorvw;

...sort(vw.begin(),vw.end());

typedef vector::iterator vwiter;

typedef pairvwiterpair;

vwiterpair p=eauql_range(vw.begin(),vw.end(),w);

if(p.first!=p.second)//如果equal_range返回非空區間,

//的下乙個位置

else

//指向w的插入位置

而且,你還可以列印出有多少個這樣的物件。

vwiterpair p=eauql_range(vw.begin(),vw.end(),w);

cout<<"there are"

<.first,p.second)<<"elements in vw equivalent to w."

;

注意:

以上我們的方法使用與序列容器如:vector,string,deque,list。

關聯容器也有count.find,equal_range,lower_bound,upper_bound成員函式。凡是前面的討論中建議選擇以上演算法的,在關聯容器中只要使用同名的成員函式即可。只有binary_search例外,因為關聯容器中沒有這個成員函式。

C STL 常用查詢演算法

find 查詢元素,內建型別 void test01 查詢在區間內出現的第乙個5,返回當前查詢元素迭代器 vector int iterator it find v.begin v.end 5 if it v.end else find 查詢元素,自定義型別,得告訴編譯器如何做對比 class pe...

C STL 演算法精選之查詢篇

1.查詢類演算法 adjacent find first,last 查詢區間 first,last 內第一次出現連續的兩個相等的元素,並返回指向第乙個元素的迭代器,連續元素之間的比較,預設是 adjacent find first,last,pred 用途如上,但是元素之間的比較是通過函式pred來...

C STL 遍歷 查詢演算法學習

一.遍歷演算法 1.for each 普通函式 void print01 int val 仿函式 class print02 void test01 for each v.begin v.end print01 cout endl for each v.begin v.end print02 int...