STL中與比較器有關的容器和演算法
一. set:包含了經過排序了的資料,這些資料的值(value)必須是唯一的。
- 標頭檔案: #include<set>
- 定義:定義一個元素為整數的集合a,可以用 set<int> a;
- 基本操作:
- 對集合a中元素的有
- 插入元素:a.insert(1);
- 刪除元素(如果存在):a.erase(1);
- 判斷元素是否屬於集合:if (a.find(1) != a.end()) ...
- 返回集合元素的個數:a.size()
- 將集合清為空集:a.clear()
- 集合的並,交和差
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。
- 注意以下幾點:
- 對於內建型別如int, double, float, string等,比較器以及輸入輸出操作符是系統已經定義好的;對於class, struct等型別,比較器即輸入輸出操作符都需重新寫;如struct Teacher裡面定義了比較器及過載輸出操作符;
- set裡面的元素有序且唯一,在預設的情況下,是按從小到大排序的;如果想讓元素從大到小排序,則需要在定義集合時,模板引數中需加greater比較器,而且這裡的引數是結構體本身,因此是greater<Teacher>,而不是物件greater<Teacher>();但是在sort函式中的比較器,則是物件。
- 例子程式:
二. 輸入輸出重新定向
- 例子程式:
- 說明:若main中只有語句(3), 則直接執行OutputInfo(),並且將內容輸入到螢幕上;
- 問題:若不想改變函式本身,如何將OutputInfo()中的語句輸入到outfile這個檔案中,即語句(1)所建的檔案?
- 答: 加上第(2)和(4)語句;
三. priority_queue: 優先佇列
- 標頭檔案: #include<queue>
- 模板原型:priority_queue<T,Sequence,Compare>
- T:存放容器的元素型別
- Sequence:實現優先順序佇列的底層容器,預設是vector<T>
- Compare:用於實現優先順序的比較函式,預設是functional中的less<T>
- 基本操作:
- empty() 如果優先佇列為空,則返回真
- pop() 刪除第一個元素
- push() 加入一個元素
- size() 返回優先佇列中擁有的元素的個數
- top() 返回優先佇列中有最高優先順序的元素
- 注意一下幾點:
- priority_queue放置元素時,不會判斷元素是否重複。(因為在模板的第二個引數是順序容器,不能保證元素的唯一性)
- 預設情況下(預設比較器是less),大的優先,即按順序輸出是從大到小的;
- 若要從小到大輸出,則在定義優先佇列物件時,模板引數上要加大於比較器;由於優先佇列模板引數有三個,所以若加比較器作為引數,則第二個引數也不能省,一般就用預設的vector<>;
- 優先佇列預設的情況是從大到小的順序,而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型別
- back_inserter() 它使用容器的push_back()插入操作,如 unique_copy( ivec.begin(), ivec.end(),back_inserter( afterUnique );//現在用 afterUnique.push_back()
- 插入front_inserter() 它使用容器的push_front()插入操作,但是注意vector 類不支援push_front()
- inserter() 它呼叫容器的insert()插入操作代替賦值操作符inserter()要求兩個實參