STL之set、multiset用法
概述
- STL关联容器能通过关键字(search key)直接访问从而存储和读取元素。在关联容器中按排序顺序维护关键字。对关联容器迭代时,按该容器的排列顺序遍历。
- set和multiset类提供了控制数值集合的操作,其中数值是关键字。
- set和multiset通常实现为红黑折半查找树,因为折半查找树通常是平衡的,从而减少平均查找时间。
- multiset与set的区别:multiset允许重复键,而set不允许重复键。
- 元素的顺序由比较器函数对象确定。如整型set/multiset升序排列的话要用比较器函数对象less,其条件是使用less的关键字必须支持operator<的比较。如果关联容器为自定义的数据类型,则这些类型应提供相应的比较运算符。
- set关联容器用于快速存储和读取唯一的关键字。multiset关联容器用于快速存储和读取关键字。如果在set中插入重复关键字,则忽略重复值(这是set的数学行为,不作为常见编程错误)。
- set和multiset支持双向迭代器。
具体用法
0. 头文件
#include<set>
1. 声明和初始化
用 typedef 使得类型名较长的代码更方便读写
//声明一个set,按升序排列,默认升序排列
set<int>set1;
或 set<int,less<int>>set1;
//声明一个multiset,按升序排列,默认升序排列
multiset<int>set1;
或 multiset<int,less<int>>set1;
//用typedef生成用函数对象less<int>按升序排列的整型multiset类型,
//这个新类型用于实例化一个整型multiset对象set1
typedef multiset<int, less<int>> ims;
ims set1;
//声明一个multiset,按降序排列
multiset<int, greater<int>>set1;
或
typedef multiset<int, greater<int>> ims;
ims set1;
//声明一个set1,将set2赋值给set1
ims set1=set2;
或 ims set1(set2);
或 ims set1(set2.begin(),set2.end());
//声明一个set1,赋值{1,2,3,4}
ims set1={1,2,3,4};
//声明一个set1,将数组a[0]到a[4]赋值给set1
ims set1=(a,a+5);
或 ims set1=(&a,&a+5);
//生成一个set1,将大小设为10,且每个元素都为设置为5
ims set1(10,5);
2. 常用函数(查询)
2.1 empty()
set1.empty(); //返回值bool类型,若set1为空,则返回true
2.2 size()
set1.size(); //返回值为int类型,set1当前存放的元素的个数
2.3 find()
//返回iterator,指向第一个找到数值2的位置,若找不到则返回的iterator等于set1.end()
set1.find(2);
2.4 lower_bound()
//返回set1中第一个找到数值2的位置的iterator,如果找不到则返回end()
set1.lower_bound(2);
2.5 upper_bount()
//返回set1中最后一个找到数值2的位置的后一个位置的iterator,如果找不到则返回end()
set1.upper_bound(2);
2.6 equal_range()
//声明一个pair类对象p,pair类对象用于操作数值对
//pair类型包含两个public数据成员first和second
//在这里,pair的内容是整型multiset的两个iterator。
pair<ims::iterator, ims::iterator> p;
//确定set1中数值2的lower_bound和upper_bound,返回类型为pair
p=set1.equal_range(2);
2.7 count()
set1.count(2); //确定set1中数值2出现的次数
2.8 迭代器
set的迭代器通常实现为set元素的指针。
//开始指针(正向)
set1.begin()
//结束指针(正向),指向set1最后一个元素的后一位
set1.end()
//开始指针(逆向)
set1.rbegin()
//结束指针(逆向),指向set1最后一个元素的后一位
set1.rend()
//常量开始指针(正向),不能通过该指针来修改所指内容
set1.cbegin()
//常量结束指针(正向),不能通过该指针来修改所指内容,指向set1最后一个元素的后一位
set1.cend()
2.9 输出
//迭代器,顺序访问
for (set<int>::iterator p = nums.begin(); p != nums.end(); p++)
cout << *p << " ";
或
for (multiset<int>::iterator p = nums.begin(); p != nums.end(); p++)
cout << *p << " ";
//迭代器,逆序访问
for (set<int>::reverse_iterator p = nums.rbegin(); p != nums.rend(); p++)
cout << *p << " ";
//输出迭代器,copy算法
ostream_iterator<int> output(cout, " ");
copy(set1.begin(),set1.end(),output);
cout<<endl;
3. 常用函数(操作)
3.1 insert()
若是set的话,插入重复的值会失败,但不会报错,只是直接忽略。因此用pair类存储insert()的返回值。pair<set::iterator, bool> p=set1.insert(10);来判断是否插入成功。
若插入成功,p.first=插入的该值的迭代器位置,p.second=true;
若插入失败,p.first=第一个找到该值的迭代器位置,p.second=false;
//在set1中插入值2,由于声明了升序排列,插入后set将保持升序
set1.insert(2);
//在set1中插入数组a[0]到a[4]的内容
set1.insert(a, a + 5);
3.2 erase()
//在set1中删除迭代器指向的元素
set1.erase(set1.begin());
//在set1中删除迭代器指向的区间的全部元素
set1.erase(set1.begin(),set1.end());
//在set1中删除元素等于10的所有副本
set1.erase(10);
3.3 swap()
//将set1和set2交换
set1.swap(set2);
3.4 resize()
//重置set1的大小为10
set1.resize(10);
4. 常用算法
4.0 头文件
#include<algorithm>
4.1 copy()
//将set2从头到尾的内容复制给set1
copy(set2.begin(),set2.end(),set1);
//输出set1的内容
copy(set1.begin(),set2.end(),ostream_iterator<int>(cout," "));