STL学习笔记-set/multiset容器(集合)

简介:
set中包含的元素是唯一的,集合中的元素是按照排序规则存放的,不能指定插入的位置
set采用红黑树变体的数据结构实现,属于 平衡二叉树。在插入和删除操作上比vector快
set不能用at(pos)和[]直接存取元素
multiset与set区别:set支持唯一键值,每个元素只能出现一次,但multiset中同一元素可以出现多次
不能直接修改set/multiset中元素的值,因为该容器是自动排序的。如果要修改一个元素值,应先删除,再插入

头文件:
#include<set>

基本操作:
set<int> s;    //默认从小到大排列
s.insert(20); //插入元素
s.insert(30); 
s.insert(20); 
s.insert(40); 
//遍历set
for(set<int>::iterator it = s.begin(); it != s.end(); it++) {
    cout << *it << endl;
}
//删除元素
while(!s.empty()) {
     set<int>::iterator it2 = s.begin();
     s.erase(it2);
}

改变自动排序的规则:
set<int> s1; //从小到大
set<int, less<int>> s2; //从小到大
set<int, greater<int>> s3; //从大到小
s3.insert(10); //插入元素
s3.insert(30); 
s3.insert(20); 
s3.insert(40); 
//注意此时的迭代器也要变
for(set<int, greater<int>>::iterator it = s3.begin(); it != s3.end(); it++) {
    cout << *it << endl;
}

如何对自定义数据类型(如 student类)按照规则进行自动排序?----> 仿函数应用
//自定义数据类型
class Student{
public:
     int age;
     char name[64];    
     void printStuInfo() {
          cout << "age : " << age << endl;
     }
};

//仿函数
struct CompStudent{
     bool operator()(const Student& left, const Student& right) {
        if(left.age < right.age)
              return true; //左小返回真,则从小到大排序
          else
              return false;
     }    
}

set<Student, CompStudent> s1;
Student stu1, stu2, stu3;
stu1.age = 28;
stu2.age = 19;
stu3.age = 20;

s1.insert(stu1); 
s1.insert(stu2); 
s1.insert(stu3); 
//注意此时的迭代器也要变
for(set<Student, CompStudent>::iterator it = s1.begin(); it != s1.end(); it++) {
    cout << it->age << endl;
}

如果两个student的age一样,则在上面情形下,后插入的那个会被忽略掉,如何判断
插入是否成功?----> 看insert的返回值---->pair的应用
Student stu4;
stu4.age = 28;
pair<set<Student, CompStudent>::iterator, bool> pair1 = s1.insert(stu4);
if(pair1.second == false) {
    cout<< "failed." << endl;
}

set查找:
set.find(elem); // 查找elem元素,返回指向该元素的迭代器
set.count(elem); //返回elem的个数,对set,要么0,要么1,对multiset可能大于1
set.lower_bound(elem); //返回第一个>=elem的元素的迭代器
set.upper_bound(elem); //返回第一个>elem的元素的迭代器
set.equal_range(elem); //返回容器中与elem相等的上下限两个迭代器,在pair的形式返回,
                                         //上限闭区间,下限开区间[begin, end)
equal_range使用示例:
set<int> s1; 
s1.insert(10); 
s1.insert(30); 
s1.insert(20); 
s1.insert(40); 
pair<set<int>::iterator, set<int>::iterator> p = s1.equal_range(30);
set<int>::iterator it1 = p.first;
cout<<*it1<<endl; //因为是>= 应该是30
set<int>::iterator it2 = p.second;
cout<<*it2<<endl; //因为是> 应该是40

p = s1.equal_range(25);
it1 = p.first;
cout<<*it1<<endl; //因为是>= 应该是30
it2 = p.second;
cout<<*it2<<endl; //因为是> 应该是30

multiset基本操作:
因为允许重复元素,自动排序可能出现1,2,2,2,3这样的顺序,其他和set一样
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值