set容器內的元素會被自動排序,set與map不同,set中的元素即是鍵值又是實值,set不允許兩個元素有相同的鍵值。不能通過set的迭代器去修改set元素,原因是修改元素會破壞set組織。當對容器中的元素進行插入或者刪除時,操作之前的所有迭代器在操作之后依然有效。
multiset特性及用法和set完全相同,唯一的差別在於它允許鍵值重復。
set和multiset的底層實現是一種高效的平衡二叉樹,即紅黑樹(Red-Black Tree)。
以下代碼涉及的內容:
1、set容器中,元素類型為基本類型,如何讓set按照用戶意願來排序?
2、set容器中,如何讓元素類型為自定義類型?
3、set容器的insert函數的返回值為什么類型?

1 #include <iostream> 2 #include <string> 3 #include <set> 4 using namespace std; 5 6 /* 仿函數CompareSet,在test02使用 */ 7 class CompareSet 8 { 9 public: 10 //從大到小排序 11 bool operator()(int v1, int v2) 12 { 13 return v1 > v2; 14 } 15 //從小到大排序 16 //bool operator()(int v1, int v2) 17 //{ 18 // return v1 < v2; 19 //} 20 }; 21 22 /* Person類,用於test03 */ 23 class Person 24 { 25 friend ostream &operator<<(ostream &out, const Person &person); 26 public: 27 Person(string name, int age) 28 { 29 mName = name; 30 mAge = age; 31 } 32 public: 33 string mName; 34 int mAge; 35 }; 36 37 ostream &operator<<(ostream &out, const Person &person) 38 { 39 out << "name:" << person.mName << " age:" << person.mAge << endl; 40 return out; 41 } 42 43 /* 仿函數ComparePerson,用於test03 */ 44 class ComparePerson 45 { 46 public: 47 //名字大的在前面,如果名字相同,年齡大的排前面 48 bool operator()(const Person &p1, const Person &p2) 49 { 50 if (p1.mName == p2.mName) 51 { 52 return p1.mAge > p2.mAge; 53 } 54 return p1.mName > p2.mName; 55 } 56 }; 57 58 /* 打印set類型的函數模板 */ 59 template<typename T> 60 void PrintSet(T &s) 61 { 62 for (T::iterator iter = s.begin(); iter != s.end(); ++iter) 63 cout << *iter << " "; 64 cout << endl; 65 } 66 67 void test01() 68 { 69 //set容器默認從小到大排序 70 set<int> s; 71 s.insert(10); 72 s.insert(20); 73 s.insert(30); 74 75 //輸出set 76 PrintSet(s); 77 //結果為:10 20 30 78 79 /* set的insert函數返回值為一個對組(pair)。 80 對組的第一個值first為set類型的迭代器: 81 1、若插入成功,迭代器指向該元素。 82 2、若插入失敗,迭代器指向之前已經存在的元素 83 84 對組的第二個值seconde為bool類型: 85 1、若插入成功,bool值為true 86 2、若插入失敗,bool值為false 87 */ 88 pair<set<int>::iterator, bool> ret = s.insert(40); 89 if (true == ret.second) 90 cout << *ret.first << " 插入成功" << endl; 91 else 92 cout << *ret.first << " 插入失敗" << endl; 93 } 94 95 void test02() 96 { 97 /* 如果想讓set容器從大到小排序,需要給set容 98 器提供一個仿函數,本例的仿函數為CompareSet 99 */ 100 set<int, CompareSet> s; 101 s.insert(10); 102 s.insert(20); 103 s.insert(30); 104 105 //打印set 106 PrintSet(s); 107 //結果為:30,20,10 108 } 109 110 void test03() 111 { 112 /* set元素類型為Person,當set元素類型為自定義類型的時候 113 必須給set提供一個仿函數,用於比較自定義類型的大小, 114 否則無法通過編譯 115 */ 116 set<Person,ComparePerson> s; 117 s.insert(Person("John", 22)); 118 s.insert(Person("Peter", 25)); 119 s.insert(Person("Marry", 18)); 120 s.insert(Person("Peter", 36)); 121 122 //打印set 123 PrintSet(s); 124 } 125 126 int main(void) 127 { 128 //test01(); 129 //test02(); 130 //test03(); 131 return 0; 132 }
以下代碼涉及的內容:
1、multiset容器的insert函數返回值為什么?

1 #include <iostream> 2 #include <set> 3 using namespace std; 4 5 /* 打印set類型的函數模板 */ 6 template<typename T> 7 void PrintSet(T &s) 8 { 9 for (T::iterator iter = s.begin(); iter != s.end(); ++iter) 10 cout << *iter << " "; 11 cout << endl; 12 } 13 14 void test(void) 15 { 16 multiset<int> s; 17 s.insert(10); 18 s.insert(20); 19 s.insert(30); 20 21 //打印multiset 22 PrintSet(s); 23 24 /* multiset的insert函數返回值為multiset類型的迭代器, 25 指向新插入的元素。multiset允許插入相同的值,因此 26 插入一定成功,因此不需要返回bool類型。 27 */ 28 multiset<int>::iterator iter = s.insert(10); 29 30 cout << *iter << endl; 31 } 32 33 int main(void) 34 { 35 test(); 36 return 0; 37 }
函數 | 功能 |
set<T> st | set默認構造函數 |
mulitset<T> mst | multiset默認構造函數 |
set(const set &st) | 拷貝構造函數 |
函數 | 功能 |
set& operator=(const set &st) | 重載等號操作符 |
swap(st) | 交換兩個集合容器 |
函數 | 功能 |
size() | 返回容器中元素的數目 |
empty() | 判斷容器收為空 |
函數 | 功能 |
insert(elem) | 在容器中插入元素。 |
clear() | 清除所有元素 |
erase(pos) | 刪除pos迭代器所指的元素,返回下一個元素的迭代器 |
erase(beg, end) | 刪除區間[beg,end)的所有元素 ,返回下一個元素的迭代器 |
erase(elem) | 刪除容器中值為elem的元素 |
函數 | 功能 |
find(key) | 查找鍵key是否存在,若存在,返回該鍵的元素的迭代器;若不存在,返回set.end() |
count(key) | 查找鍵key的元素個數 |
lower_bound(keyElem) | 返回最后一個key<=keyElem元素的迭代器 |
upper_bound(keyElem) | 返回第一個key>keyElem元素的迭代器 |
equal_range(keyElem) | 返回容器中key與keyElem相等的上下限的兩個迭代器,這兩個迭代器被放在對組(pair)中 |