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 }
输出结果: