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 }
使用set容器需要注意的细节

以下代码涉及的内容:

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 }
使用multiset容器需要注意的细节
set构造函数
函数 功能
set<T> st set默认构造函数
mulitset<T> mst multiset默认构造函数
set(const set &st) 拷贝构造函数
set赋值操作
函数 功能
set& operator=(const set &st)

重载等号操作符

swap(st) 交换两个集合容器
set大小操作
 函数  功能
 size()  返回容器中元素的数目
 empty()  判断容器收为空
set插入和删除操作
函数 功能
insert(elem) 在容器中插入元素。
clear() 清除所有元素
erase(pos) 删除pos迭代器所指的元素,返回下一个元素的迭代器
erase(beg, end) 删除区间[beg,end)的所有元素 ,返回下一个元素的迭代器
erase(elem) 删除容器中值为elem的元素
set查找操作
函数 功能
find(key) 查找键key是否存在,若存在,返回该键的元素的迭代器;若不存在,返回set.end()
count(key) 查找键key的元素个数
lower_bound(keyElem) 返回最后一个key<=keyElem元素的迭代器
upper_bound(keyElem) 返回第一个key>keyElem元素的迭代器
equal_range(keyElem) 返回容器中key与keyElem相等的上下限的两个迭代器,这两个迭代器被放在对组(pair)中
原文地址:https://www.cnblogs.com/yongqiang/p/5746754.html