C++ STL set/multset
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)中 |