文章目录
讲在前面
文章中的STL的知识还不完善,文章在不断的完善中
一、set和multiset
集合类,提供了控制数字(包括字符及串)集合的操作。
自动将元素排序,两者的操作方法基本相同,但是multiset允许元素重复,而set不允许重复即如果向set中添加重复元素时,会被set自动忽略
1.set和multiset的定义
set c //建立一个空的set/multiset 集合
set c(op) //以op为排序准则建立一个空集
set c1(c2) //建立一个集合c1,并用c2集合初始化
set c(beg, end) //用区间[beg, end]建立一个集合c
set可以是:
set/multiset<T> //建立T类型的,以less<>(从小到大)的排序集合
set/multiset<T, op> //建立T类型的,以op指定排序规则的集合
//其中,op可以是less<>或greater<>之一,应用时须在<>中写上类型,如greater<int>。
//less指定排序方式为从小到大
//greater指定排序方式为从大到小,默认排序方式为less。
2.set和multiset的赋值比较运算
– set和multiset支持>、>=、<、<=、!=、==比较运算。例如,若有集合c1、c2,可以用c1==c2,c1>c2对它们进行相等或大于判断。
– 可以赋值运算符“=”进行集合赋值,如c1=c2。
3.set和multiset计算容量
size() //计算容器的大小
empty() //判断容器是否为空,若为空则返回0
max_size() //返回容器能够保存的最大元素个数
4.set和multiset的常用操作
count(e) //计算集合中元素e的个数
find(e) //查找集合中第1次出现元素e的位置
lower_bound(e) //查找集合中第1个“元素值>=e”的位置
upper_bound(e) //查找集合中第1个“元素值>e”的位置
insert(e) //在当前集合中插入元素e;
insert(pos, e) //将e插入到pos位置
insert(beg, end) //将[beg, end]区间内的所有元素插入到当前集合中
erase(e) //删除集合中的元素e
erase(pos) //删除集合中指定位置pos的元素
erase(beg,end) //删除区间[beg,end]的所有元素
clear() //清空集合
begin() //指向第1个元素位置,常与迭代器结合应用
end() //指向最后元素的下一位置,常与迭代器结合应用
代码Demo(加深理解)
#include<iostream>
#include<string>
#include<set>
using namespace std;
void main()
{
int a1[]={-2,0,30,12,6,7,12,10,9,10};
set<int,greater<int> >set1(a1,a1+7);
set<int,greater<int> >::iterator p1;
set1.insert(12);
set1.insert(12); //向集合插入元素
set1.insert(4);
for(p1=set1.begin();p1!=set1.end();p1++)
cout<<*p1<<" "; //输出集合中的内容,它是从大到小的
cout<<endl;
string a2[]={"杜明","王为","张清山","李大海","黄明浩",
"刘一","张三","林浦海","王小二","张清山"};
//定义字符串的multiset集合,默认排序从小到大
multiset<string>set2(a2,a2+10);
multiset<string>::iterator p2;
set2.insert("杜明"); set2.insert("李则");
for(p2=set2.begin();p2!=set2.end();p2++)
cout<<*p2<<" "; //输出集合内容
cout<<endl;
string sname;
cout<<"输入要查找的姓名:";
cin>>sname; //输入要在集合中查找的姓名
p2=set2.begin();
bool s=false; //s用于判定找到姓名与否
while(p2!=set2.end()){
if(sname==*p2) { //如果找到就输出姓名
cout<<*p2<<endl;
s=true;
}
p2++;
}
if(!s)
cout<<sname<<"不在集合中!"<<endl; //如果没有找到就给出提示
}
二、map和multimap
– map和multimap提供了操作<键,值>对的方法(其中的值也称为映射值),它们存储一对对象,即键对象和值对象,键对象是用于查找过程中的键,值是与键对应的附加数据
– map中的元素不允许重复,而multimap中的元素是可以重复的。
<键,值>通过p->first、p->second来获得
常用操作
insert(e) //将元素e插入到map,multimap,set,multiset
make_pair(e1,e2)
//map/multimap类型的迭代器提供了两个数据成员:一个是first,用于访问键;另一个是second,用于访问值
//p->first p->second
代码Demo(加深理解)
//查雇员的工资
#include<iostream>
#include<string>
#include<map>
using namespace std;
void main(){
string name[]={"张大年","刘明海","李煜"}; //雇员姓名
double salary[]={1200,2000,1450}; //雇员工资
map<string,double>sal; //用映射存储姓名和工资
map<string,double>::iterator p; //定义映射的迭代器
for(int i=0;i<3;i++)
sal.insert(make_pair(name[i],salary[i])); //将姓名/工资加入映射
sal["tom"]=3400; //通过下标运算加入map元素
sal["bob"]=2000;
for(p=sal.begin();p!=sal.end();p++) //输出映射中的全部元素
cout<<p->first<<"\t"<<p->second<<endl; //输出元素的键和值
string person;
cout<<"输入查找人员的姓名:";
cin>>person;
for(p=sal.begin();p!=sal.end();p++) //据姓名查工资,找到就输出
if(p->first==person)
cout<<p->second<<endl;
}
个人小感慨
看了代码样例之后逐渐的理解了map,有句话感觉非常管用
map<string,double>sal; //用映射存储姓名和工资
map<string,double>::iterator p; //定义映射的迭代器
for(int i=0;i<3;i++)
sal.insert(make_pair(name[i],salary[i])); //将姓名/工资加入映射
……
for(p=sal.begin();p!=sal.end();p++) //输出映射中的全部元素
cout<<p->first<<"\t"<<p->second<<endl; //输出元素的键和值
感觉这个东西解决了我以前为了把数据对应到某个东西上(比如姓名对应成绩)而苦苦去写结构体的难题
而且排序也更加方便(经过尝试,一边的数据改变之后,对应的数据的顺序也会随着改变,详情见Problem K)