一、集合(set)
set是关联容器的一种,是排序好的集合( 元素已经进行了排序 ),set中不能有重复的元素。
(1)set是STL中一个很有用的容器,用来存储同一种数据类型的数据结构。
(2)set与数组不同的是,在set中每个元素的值都是唯一的。set不允许插入重复数据,而multiset允许插入相同的数据。
(3)set插入数据时,能够根据元素的值自动进行排序。新元素插入的位置取决于它的值,查找速度快。
(4)set中数元素的值不能直接被修改。(如要修改,正确的做法是先删除该元素,再插入新元素。)
set支持双向迭代器(不支持随机迭代器),在插入和删除时,要特别注意。
在STL中使用结构体,需要对特定要求的运算符进行重载;STL默认使用小于号来排序, 因此,默认重载小于号;(如果使用greater<>比较器就需重载大于号),且要注意让比较函数对相同元素返冋false。
set的定义:
set<int> a; // 定义一个int类型的集合a
set<int> b(a); // 定义并用集合a初始化集合b
set<int> b(a.begin(), a.end()); // 将集合a中的所有元素作为集合b的初始值
set的常用函数(multiset使用方法类似)

set的代码示例:
#include<iostream>
#include<set>
using namespace std;
int main(){
set<int> s; //定义长度为0的set
int a[]={50,10,30,10,20,40};
//默认比较器是less<T>:由小到大
set<int,less<int> > s1(a,a+6); //利用数组初始显set
//可以使用greater<T>比较器:由大到小
set<int,greater<int> > s2(a,a+6);
//插入到特定位置:意义不大,因为插入结束后会重新排序
cout<<s2.size()<<endl;//大小为5
s2.insert(50); s2.insert(50); s2.insert(50);
cout<<s2.size()<<endl;//自动去重,大小仍然是5
s1.insert(s1.begin(),60);
s2.insert(60);
s1.erase(s1.begin()); //删除set中的第1个元素
s1.erase(40); //删除值为元素40
set<int>::iterator it; //定义迭代器,遍历set中的元素
it=s1.find(50);
cout<<*it<<endl;
//*it=300; //错误,不能直接修改set中的元素
if(it != s1.end()){
cout<<*it<<"存在! "<<endl;
}else{
cout<<"元素不存在! "<<endl;
}
for(it=s1.begin();it!=s1.end();it++){
cout<<*it<<" ";
}
cout<<endl;
return 0;
}
set存放结构体
#include<bits/stdc++.h>
using namespace std;
struct Student{ //存放同学信息的结构体
int num;
string name;
int score;
bool operator<(const Student &s) const{ //重载运算符<
//规则:按照分数降序,分数相同按照学号降序
if(score<s.score||score==s.score &&num<s.num){
return true;
}else{
return false;
}
}
bool operator>(const Student &s) const{ //重载运算符>
//规则:按照分数降序,分数相同按照学号降序
if(score>s.score||score==s.score &&num>s.num){
return true;
}else{
return false;
}
}
};
int main(){
set<Student> s;
//set<Student, greater<Student> > s;
Student s1={2,"Zhang",100};
Student s2={3,"Wang",98};
Student s3={1,"li",98};
Student s4={3,"Wang",98};
s.insert(s1);
s.insert(s2);
s.insert(s3);
s.insert(s4);
set<Student>::iterator it;
for(it=s.begin();it!=s.end();it++){
cout<<it->num<<" "<<it->name<<" "<<it->score<<endl;
}
return 0;
}
注意:
- (1) 当在STL应用使用结构体,需要对特定要求的运算符进行重载;STL中的排序都是默认使用小于号来排序,因此,在对结构体排序时,我们就需要重载小于号!
- (2) 如果要使用grcater<Student>比较器,就要对>比较运算符进行重载。
- (3) 要注意:让比较函数对相同元素返回false。

二、多重集合(multiset)
multiset 是维护有序可重集合的容器,容器定义在头文件 set 中,基本操作与 set 类似,对于 multiset 类型的变量 ms,以下为multiset特有的方法:
ms.erase(value):从集合中删除给定值的所有元素。
ms.equal_range(value):查询一个给定值在集合中出现的范围,用pair的形式返回迭代器对。