C++ STL(八)容器_set和multiset

set(集合)是一个集合容器,容器中的元素是唯一的,元素即是键值又是实值,集合中的元素按一定的顺序排序.属于关联式容器的一种.

元素插入过程是按排序规则插入,不能指定插入位置.

它不支持随机存取元素,不能使用数组[]和at方式进行访问.

set与multiset区别:set每个元素值在容器中只能出现一次,而multiset可以出现多次

所需头文件:#include<set>

构造函数:

 1     //set
 2     set<int> setA; //构造个空的set
 3     set<int> setB(setA); //通过setA拷贝构造一个set (setB=setA)
 4     int nArray[] = {1,2,3};
 5     int nLeng = sizeof(nArray)/sizeof(int);
 6     set<int> setC(nArray, nArray+nLeng); //通过数组拷贝构造一个setC (setC={1,2,3})
 7     //使用迭代器构造    
 8     set<int> dIt(setC.begin(),setC.end()); //正向迭代器方式构造set (dIt={1,2,3,4,5})
 9     set<int> dRit(setC.rbegin(), setC.rend()); //反向迭代器方式构造set (dRit={5,4,3,2,1})
10     
11     //multiset
12     multiset<int> multisetA; //构造个空的multiset
13     multiset<int> multisetB(multisetA); //通过multisetA拷贝构造一个multiset (multisetB=multisetA)
14     nLeng = sizeof(nArray)/sizeof(int);
15     multiset<int> multisetC(nArray, nArray+nLeng); //通过数组拷贝构造一个multisetC (multisetC={1,2,3})
16     //使用迭代器构造
17     multiset<int> dItM(multisetC.begin(), multisetC.end()); //正向迭代器方式构造multisetC (dItM={1,2,3,4,5})
18     multiset<int> dRiM(multisetC.rbegin(), multisetC.rend()); //反向迭代器方式构造multisetC (dRiM={5,4,3,2,1})
19 
20     return;
构造函数

增加元素操作:

注意:set中元素是唯一的,无法插入重复的元素.multiset中可以插入重复的元素. 二种容器插入后都会自动进行排序

 1     //set中元素是唯一的,无法插入重复的元素
 2     set<int> setA;
 3     setA.insert(1);
 4     setA.insert(2);
 5     setA.insert(3);
 6     pair<set<int>::iterator,int> pairSet;
 7     pairSet = setA.insert(2); //此时由于容器中己有元素值2,就不会插入新元素2. 此时setA={1,2,3}
 8     //根据返回值pair的第二个参数可以发现插入失败
 9     if(pairSet.second == 0)
10     {
11         printf("set插入失败\r\n");
12     }
13     else if(pairSet.second == 1)
14     {
15         printf("set插入成功\r\n");
16     }
17     //迭代器方式插入
18     setA.insert(setA.end(),4); //setA={1,2,3,4}
19     set<int> setB;
20     setB.insert(setA.begin(), setA.end()); //把setA中所有元素插入到setB中
21 
22 
23     //multiset中可以插入重复的元素
24     multiset<int>::iterator it;
25     multiset<int> multisetA;
26     multisetA.insert(1); 
27     multisetA.insert(2); 
28     it = multisetA.insert(3); //it指向插入后新元素3的位置
29     it = multisetA.insert(2); //it指向插入后新元素2的位置,证明multiset可以插入重复的元素
30     //迭代器方式插入
31     multisetA.insert(multisetA.end(),4); //multisetA={1,2,2,3,4}
32     multiset<int> multisetB;
33     multisetB.insert(multisetA.begin(), multisetA.end()); //把multisetA中所有元素插入到multisetB中
34 
35     //注意:set的insert()返回的是pair,而multiset返回的是指向插入后新元素位置的迭代器
36     return;
增加元素操作

删除元素操作:

注意:set中元素是唯一的,所以删除时只会删除1个元素.multiset中元素可以是重复的,所以根据key进行删除时只要相同的都会批量删除

 1     //set中元素是唯一的,所以删除时只会删除1个元素
 2     set<int> setA;
 3     setA.insert(1);
 4     setA.insert(2);
 5     setA.insert(3);
 6 
 7     setA.erase(1); //删除元素1  setA={2,3}
 8     setA.erase(setA.begin()); //使用迭代器删除指向开始位置的元素 setA={3}
 9     setA.clear(); //清除所有元素
10 
11 
12     //multiset中元素可以是重复的,所以根据key进行删除时只要相同的都会批量删除
13     multiset<int> multisetA;
14     multisetA.insert(1);
15     multisetA.insert(1);
16     multisetA.insert(2);
17 
18     multisetA.erase(1); //所有元素值为1的元素都被删除了,最终multisetA={2}
19     multisetA.erase(multisetA.begin()); //使用迭代器删除指向开始位置的元素 multisetA={}
20     multisetA.clear(); //清除所有元素
21 
22     return;
删除元素操作

获取大小:

empty()  返回是否为空

size()     返回大小

max_size()  返回所能存储的最大元素个数,这是由系统自动定义的值

 1     //set
 2     set<int> setA;
 3     bool bEmpty = setA.empty(); //bEmpty = true
 4     int nSize = setA.size();    //nsize = 0
 5     setA.insert(1);
 6     bEmpty = setA.empty(); //bEmpty = false
 7     nSize = setA.size();  //nSize = 1
 8     int nMaxSize = setA.max_size(); //nMaxSize = 214748364 所能存储的最大元素个数,这是由系统自动定义的值
 9 
10     //mulitset
11     multiset<int> multisetA;
12     bEmpty = multisetA.empty(); //bEmpty = true
13     nSize = multisetA.size();    //nsize = 0
14     multisetA.insert(1);
15     multisetA.insert(1);
16     bEmpty = multisetA.empty(); //bEmpty = false
17     nSize = multisetA.size();  //nSize = 2
18     nMaxSize = multisetA.max_size(); 
19 
20     return;
获取大小

查找操作:

find()  根据元素值进行查找,返回第一个找到的迭代器

count(key) 根据元素值进行查找,返回元素个数. 注意: set返回的只有可能是0或者1,而multiset返回的可能是0和>0的元素个数

lower_bound(elem) 返回第一个>=elem元素的迭代器

upper_bound(elem) 返回第一个> elem元素的迭代器

equal_range(elem) 返回容器中与elem相等的包含上下限二个迭代器的pair

 1     set<int> setInt;
 2     setInt.insert(11);
 3     setInt.insert(13);
 4     setInt.insert(22);
 5     setInt.insert(9);
 6     setInt.insert(7);
 7 
 8     //find 根据元素值进行查找,返回第一个找到的迭代器
 9     set<int>::iterator it = setInt.find(9);
10     int nValue = *it; //nValue = 9
11 
12     //count 根据元素值进行查找,返回元素个数
13     //因为set中元素是唯一的,所以count()返回的只有可能是0或者是1
14     //而multiset中元素值可以是重复的,所以count()值可以是0,或者>=1
15     int nCount = setInt.count(99); //没有找到元素值为99的元素,nCount=0
16     nCount = setInt.count(7); //nCount = 1
17 
18     //lower_bound(elem) 返回第一个>=elem元素的迭代器
19     //upper_bound(elem) 返回第一个> elem元素的迭代器
20     set<int>::iterator itLower = setInt.lower_bound(13); //*itLower = 13
21     set<int>::iterator itUpper = setInt.upper_bound(13); //*itUpper = 22
22 
23     //equal_range(elem) 返回容器中与elem相等的包含上下限二个迭代器的pair
24     //pair是个对组,包含二个迭代器,first与second
25     //pair.first 查找的元素值所在的迭代器
26     //pair.second 查找的元素值所在的下一个迭代器
27     pair<set<int>::iterator, set<int>::iterator> itPair = setInt.equal_range(13);
28     set<int>::iterator itFirst = itPair.first; //*itFirst = 13
29     set<int>::iterator itSecond = itPair.second; //*itSecond = 22
30 
31     return;
查找操作

排序操作:

1.自动排序: 定义set和multiset时使用缺省排序或者显示指明容器排序方式. 注意:只能排序基本数据类型

 1     //自动排序,只能排序基本数据类型
 2     set<int> setA; //set和multiset使用缺省的排序方式,也就是升序排序
 3     set<int,less<int>> setLess; //setB和setA是等价的都是升序排序
 4     set<int,greater<int>> setGreater; //使用降序排序
 5 
 6     setA.insert(3);
 7     setA.insert(1);
 8     setA.insert(2);  //此时由于setA使用默认的升序排序,setA={1,2,3}
 9 
10     setLess.insert(3);
11     setLess.insert(1);
12     setLess.insert(2); //此时由于setB和setA一样也是使用升序排序,setLess={1,2,3}
13 
14     setGreater.insert(3);
15     setGreater.insert(1);
16     setGreater.insert(2); //此时由于setGreater使用降序排序,setGreater={3,2,1}
17 
18     return;
自动排序

2.编写排序函数排序:

学生包含学号,姓名属性,现要求插入几个学生对象到set容器中,使得容器中的学生按学号的升序排列.

 1 class CStudent
 2 {
 3 public:
 4     CStudent(int nId, string strName)
 5     {
 6         m_nId = nId;  //学号
 7         m_strName = strName; //学生名字
 8     }
 9 public:
10     int m_nId;
11     string m_strName;
12 };
学生对象
1 struct StuFunctor
2 {
3     bool operator()(const CStudent &stu1, const CStudent &stu2)
4     {
5         return (stu1.m_nId<stu2.m_nId); //根据nId学号进行升序排列
6         //return (stu1.m_nId>stu2.m_nId); //根据nId学号进行降序排列
7     }
8 };
学生排序函数
 1 inline void SortByFunction()
 2 {
 3     //函数对象functor的用法
 4     //学生包含学号,姓名属性,现要求插入几个学生对象到
 5     //set容器中,使得容器中的学生按学号的升序排列.
 6     set<CStudent,StuFunctor> setStu; //定义set时指定使用自定义排序函数
 7     setStu.insert(CStudent(3,"小张"));
 8     setStu.insert(CStudent(1,"小李"));
 9     setStu.insert(CStudent(5,"小王"));
10     setStu.insert(CStudent(2,"小刘"));
11     set<CStudent,StuFunctor>::iterator it = setStu.begin();
12     for (it; it!=setStu.end(); ++it)
13     {
14         cout<<it->m_nId <<":"<<it->m_strName.c_str()<<endl;
15     }
16 
17     getchar();
18     return;
19 }
演示部份

输出结果:

posted @ 2019-12-27 16:09  SmallOverFllow  阅读(339)  评论(0编辑  收藏  举报