STL之std::set、std::map的lower_bound和upper_bound函數使用說明


由於在使用std::map時感覺lower_bound和upper_bound函數了解不多,這里整理並記錄下相關用法及功能。

 

STL的map、multimap、set、multiset都有三個比較特殊的函數,lower_bound、upper_bound、equal_range。

原型如下: 

iterator lower_bound (const value_type& val) const;

iterator upper_bound (const value_type& val) const;

pair<iterator,iterator> equal_range (const value_type& val) const;

 上面三個函數是相關聯的,equal_range返回兩個迭代器,第一個迭代器是lower_bound的返回值,第二個迭代器是upper_bound的返回值。(注意是使用相同val值調用的情況下。)

msdnc++標准來看,lower_bound、upper_bound兩個函數用於記錄允許元素重復出現的數據集中給定關鍵字val在當前集合中區間范圍。

對諸如set、map這種關鍵字唯一的集合而言,lower_bound、upper_bound返回迭代器是相同,關鍵字val在集合中不存在,二者返回結果一樣,都是按照集合實例化時給定的Compare比較,不在val之前的第一個元素(亦即之后或者等於,如果按照默認的比較類型less,函數返回的是≥val的最小的元素);如果關鍵在val在集合中存在,lower_bound返回val關鍵字本身的迭代器,upper_bound返回關鍵字val下一個元素迭代器。

對multiset、multimap這類關鍵字不唯一的集合而言。按照關鍵字后面一個關鍵字在集合中出現的次數可分為:關鍵字val出現在集合中,但是是唯一的,這種情況和set、map情況類似;關鍵字val出現在集合中,出現多次,這種情況下lower_bound返回第一個出現關鍵字val對應的迭代器,upper_bound返回位於關鍵字val對應位置后第一個不是val的位置的迭代器;關鍵字val不在集合中,這種情況下與set、map一致。

綜合一下(按照默認集合升序排序的情況下),lower_bound、upper_bound函數不管在什么情況下,以下條件均成立。

Iterator(val) ≤ Iterator(lower_bound)≤Iterator(upper_bound)

也就是lower_bound、upper_bound構成的上下限的區間總是表示一個有效的迭代器區間(equal_range返回值),該迭代區間的長度表示關鍵字val在集合中出現的次數

如果二者返回值相等,表示關鍵字val在集合中未出現。(例外情況,集合中的所有元素均≥關鍵字val,返回集合的iterator::end)

如果迭代器區間長度是1,表示關鍵字val在集合中僅出現1次。

迭代器區間長度大於1,則表示關鍵字val出現多次,並且一定不是set和map這種關鍵字唯一的集合。

示例代碼:

// g++ -o setLowerUpperBoundTest setLowerUpperBoundTest.cpp

#include <set>
#include <iostream>

using namespace std ;

typedef set<int> SET_INT;

int main() 
{
  SET_INT s1;
  SET_INT::iterator i;
  cout << "s1.insert(5)" << endl;
  s1.insert(5);
  cout << "s1.insert(10)" << endl;
  s1.insert(10);
  cout << "s1.insert(15)" << endl;
  s1.insert(15);
  cout << "s1.insert(20)" << endl;
  s1.insert(20);
  cout << "s1.insert(25)" << endl;
  s1.insert(25);

  cout << "s1 -- starting at s1.lower_bound(12)" << endl;
// prints: 15,20,25
  for (i=s1.lower_bound(12);i!=s1.end();i++)
     cout << "s1 has " << *i << " in its set." << endl;

  cout << "s1 -- starting at s1.lower_bound(15)" << endl;
// prints: 15,20,25
  for (i=s1.lower_bound(15);i!=s1.end();i++)
     cout << "s1 has " << *i << " in its set." << endl;

  cout << "s1 -- starting at s1.upper_bound(12)" << endl;
// prints: 15,20,25
  for (i=s1.upper_bound(12);i!=s1.end();i++)
     cout << "s1 has " << *i << " in its set." << endl;

  cout << "s1 -- starting at s1.upper_bound(15)" << endl;
// prints: 20,25
  for (i=s1.upper_bound(15);i!=s1.end();i++)
     cout << "s1 has " << *i << " in its set." << endl;

  cout << "s1 -- s1.equal_range(12)" << endl;
// does not print anything
  for (i=s1.equal_range(12).first;i!=s1.equal_range(12).second;i++)
     cout << "s1 has " << *i << " in its set." << endl;

  cout << "s1 -- s1.equal_range(15)" << endl;
// prints: 15
  for (i=s1.equal_range(15).first;i!=s1.equal_range(15).second;i++)
     cout << "s1 has " << *i << " in its set." << endl;
}
/* Output in windows
s1.insert(5)
s1.insert(10)
s1.insert(15)
s1.insert(20)
s1.insert(25)
s1 -- starting at s1.lower_bound(12)
s1 has 15 in its set.
s1 has 20 in its set.
s1 has 25 in its set.
s1 -- starting at s1.lower_bound(15)
s1 has 15 in its set.
s1 has 20 in its set.
s1 has 25 in its set.
s1 -- starting at s1.upper_bound(12)
s1 has 15 in its set.
s1 has 20 in its set.
s1 has 25 in its set.
s1 -- starting at s1.upper_bound(15)
s1 has 20 in its set.
s1 has 25 in its set.
s1 -- s1.equal_range(12)
s1 -- s1.equal_range(15)
s1 has 15 in its set.
*/
View Code

上述代碼正好驗證並說明了lower_bound、upper_bound、equal_range三個函數的功能的功能,以及本文中的解釋。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM