1. 程式人生 > >Effective_STL 學習筆記(四十五) 注意 count、find、binary_search、lower_bound、upper_bound 和 equal_range 的區別

Effective_STL 學習筆記(四十五) 注意 count、find、binary_search、lower_bound、upper_bound 和 equal_range 的區別

 

如果區間有序,可以使用對數時間的演算法,binary_search、lower_bound、upper_bound 和 equal_range 

如果迭代器沒有劃分一個有序區間,只能用線性時間的演算法 count、count_if、find 和 find_if 

 

cout 回答: 是否存在這個值,如果有,那麼存在幾分拷貝?

find 回答: 是否存在,如果有,那麼它在哪?

 

count 返回零或一個正數,所以把非零轉換為 true 而把零轉化為 false

1     if( count(lw.begin(), lw.end(), w) )  //
檢查是否有w在lw中 2    . . .

 

使用 find 的演算法可以在搜尋到就停止,不必繼續搜尋

1   if( find( lw.begin(), lw.end(), w ) != lw.end() )
2     . . .    // 找到了
3   else
4     . . .    // 沒找到

 

想獲得區間中的第一個等於該值的物件,就得使用 find:

1   list<Widget>::iterator i = find( lw.begin(), lw.end(), w );
2   if( i != lw.end() )
3     . . .   // 找到了,i 指向第一個 4   else 5     . . .   // 沒有找到

 

有序區間搜尋演算法是線性時間的 binary_search、lower_bound、upper_bound 和 equal_range 是對數時間的,從無序區間遷移到有序區間導致另一個遷移:從使用相等來判斷兩個值是否相同到使用等價來判斷。

 

binary_searh 回答: 它在嗎?它的回答只能是是或者不是

1   if( binary_search( lw.begin(), lw.end(), w ) )
2     . . .  // w 在 lw 中
3   else 4     . . .   // w 不在 lw 中

 

如果要回答: 它在嗎,如果是,那麼在哪裡? 你就需要 equal_range,但可能想要 lower_bound

 

lower_bound 回答: 它在嗎?如果是,第一個拷貝在哪?如果不是,它將在哪裡?

lower_bound 要檢測返回值是否等於 end 迭代器,還要檢測標識物件是都為找的值

1   vector<Widget>::iterator i = lower_bound( vw.begin(), vw.end(), w );
2   if( i != vw.end() && *i == w )    //  這有一個 bug
3     . . .        
4   else
5     . . . 

大多數情況能通過,bug 在於 *i == w 這是一個相等測試,而 lower_bound 用的是等價測試

 

equal_range 返回一對迭代器,第一個等於 lower_bound 返回的迭代器,第二個等於 upper_bound 返回的迭代器。因此,equal_range 返回了一對劃分出了和你要搜尋的值的等價的區間的迭代器。

 1   vector<Widget> vw;
 2   . . .
 3   sort( vw.begin(), vw.end() );
 4   typedef vector<Widget>::iterator VWIter;
 5   typedef pair<VWIter, VWIter> VWIterPair;
 6   VWIterPair p = equal_range( vw.begin(), vw.end(), w );
 7   if( p.first != p.second )
 8     . . .  // 找到了,p.first 指向第一個,p.second 指向第二個
 9   else
10     . . .  // 沒找到 p.first 和 p.second 都指向搜尋值的插入位置 

equal_range 返回的東西是兩個迭代器,對他們作 distance 就等於區間中物件的數目,也就是等價於要尋找的值的物件。equal_range 不光完成了搜尋有序區間的任務,而且完成了計數(distance())

1   cout<<"There are"<< distance(p.first, p.second) <<"elements in vw";

 

對於標準關聯容器(set、multiset、map 和 multimap)使用它們成員函式代替同名演算法,沒有 binary_search 對應的成員函式,對於 set 或者 map 使用 count 的慣用法,對於 multiset 和 multimap 使用 find 比 count 好。