1. 程式人生 > >STL中與比較器有關的容器和演算法

STL中與比較器有關的容器和演算法

一. set:包含了經過排序了的資料,這些資料的值(value)必須是唯一的。 

  • 標頭檔案: #include<set>
  • 定義:定義一個元素為整數的集合a,可以用 set<int> a;
  • 基本操作:
  1. 對集合a中元素的有
  2. 插入元素:a.insert(1);
  3. 刪除元素(如果存在):a.erase(1);
  4. 判斷元素是否屬於集合:if (a.find(1) != a.end()) ...
  5. 返回集合元素的個數:a.size()
  6. 將集合清為空集:a.clear()
  7. 集合的並,交和差

  set_union(a.begin(),a.end(),b.begin(),b.end(),insert_iterator<set<int> >(c,c.begin()));

  set_intersection(a.begin(),a.end(),b.begin(),b.end(),insert_iterator<set<int> >(c,c.begin()));

  set_difference(a.begin(),a.end(),b.begin(),b.end(),insert_iterator<set<int> >(c,c.begin()));

  (注意在此前要將c清為空集)。

  • 預設情況:輸出的結果從小到大,即15, 25, 35, 55; 若要從大到小輸出,則這樣定義集合:set<Teacher, greater<Teacher>> teachers; 輸出的結果為:55, 35, 25, 15。
  • 注意以下幾點:
  1. 對於內建型別如int, double, float, string等,比較器以及輸入輸出操作符是系統已經定義好的;對於class, struct等型別,比較器即輸入輸出操作符都需重新寫;如struct Teacher裡面定義了比較器及過載輸出操作符;
  2. set裡面的元素有序且唯一,在預設的情況下,是按從小到大排序的;如果想讓元素從大到小排序,則需要在定義集合時,模板引數中需加greater比較器,而且這裡的引數是結構體本身,因此是greater<Teacher>,而不是物件greater<Teacher>();但是在sort函式中的比較器,則是物件。
  • 例子程式:

 

二. 輸入輸出重新定向

  • 例子程式:

 

  • 說明:若main中只有語句(3), 則直接執行OutputInfo(),並且將內容輸入到螢幕上;
  • 問題:若不想改變函式本身,如何將OutputInfo()中的語句輸入到outfile這個檔案中,即語句(1)所建的檔案?
  • 答: 加上第(2)和(4)語句;

三. priority_queue: 優先佇列

  • 標頭檔案: #include<queue>
  • 模板原型:priority_queue<T,Sequence,Compare>
  1. T:存放容器的元素型別
  2. Sequence:實現優先順序佇列的底層容器,預設是vector<T>
  3. Compare:用於實現優先順序的比較函式,預設是functional中的less<T>
  • 基本操作:
  1. empty()  如果優先佇列為空,則返回真 
  2. pop()  刪除第一個元素 
  3. push()  加入一個元素 
  4. size()  返回優先佇列中擁有的元素的個數 
  5. top()  返回優先佇列中有最高優先順序的元素 
  • 注意一下幾點:
  1.  priority_queue放置元素時,不會判斷元素是否重複。(因為在模板的第二個引數是順序容器,不能保證元素的唯一性)
  2.  預設情況下(預設比較器是less),大的優先,即按順序輸出是從大到小的;
  3.  若要從小到大輸出,則在定義優先佇列物件時,模板引數上要加大於比較器;由於優先佇列模板引數有三個,所以若加比較器作為引數,則第二個引數也不能省,一般就用預設的vector<>;
  4. 優先佇列預設的情況是從大到小的順序,而sort, binary_search 以及set 預設的都是從小到大排序的。
  • 例子程式:

此程式碼輸出結果為: 25, 15, 10, 5;

下面講有關排序方面的4個演算法:

一. sort

  • 標頭檔案: #include <algorithm>
  • 例子程式:

  • 注意:比較函式放在標頭檔案<functional>中。

二. binary_search: 二分搜尋法,要求容器是從小到大排序的,若從大到小排序了,它會找不到;它返回的是一個bool值,表示有沒有找到

  • 標頭檔案: #include <algorithm>
  • 例子程式:

 

若sort(datas.begin(), datas.end(), greater<int>());//將datas從大到小排序

bool temp = binary_search(datas.begin(), datas.end(), 0); //返回0,即沒有找到,此種情況下,可以將迭代器反過來,即

bool temp = binary_search(datas.rbegin(), datas.rend(), 0); //這樣就相當於又是對從小到大排序的陣列進行操作了

三. unique: 保證數的唯一性,但是不能保證數的有序;返回一個迭代器,指向資料唯一的末端。

  • 標頭檔案: #include <algorithm>
  • 例子程式:

 

或者

 

四. unique_copy: 保證數的唯一性,並執行拷貝操作

  • 用法看例子程式:

 

注意: datas中有元素1000個,經過唯一化後,元素必然小於等於1000;所以當afterUnique空間賦予過大時,後面的元素將會用0補;

  • 為避免這種情況,我們可以用插入迭代器,即邊插入邊分配空間。

 

  • 下面介紹幾種插入迭代器:插入迭代器提供三個介面卡函式,返回型別為insert_iterator型別
  1. back_inserter() 它使用容器的push_back()插入操作,如 unique_copy( ivec.begin(), ivec.end(),back_inserter( afterUnique );//現在用 afterUnique.push_back()
  2. 插入front_inserter() 它使用容器的push_front()插入操作,但是注意vector 類不支援push_front()
  3. inserter() 它呼叫容器的insert()插入操作代替賦值操作符inserter()要求兩個實參