分类
Level5

set

一、集合(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的形式返回迭代器对。