四、常用容器(Pair、Map、Multimap)
2018-06-29 本文已影响18人
木鱼_cc
1. Pair对组
类模板:template <class T1, class T2> struct pair
参数:T1是第一个值的数据类型,T2是第二个值的数据类型。
功能:pair将一对值组合成一个值,这一对值可以具有不同的数据类型(T1和T2),两个值可以分别用pair的两个公有函数first和second访问。
//第一种方式 创建一个Pair
pair<int,string> mypair(10,"aaa");
cout<<mypair.first<<" "<<mypair.second<<endl;
//第二种 创建Pair
pair<string,string> mypair2 = make_pair("aaa","bbb");
//等价于 auto mypair2 = make_pair("aaa","bbb");
cout<<mypair2.first<<" "<<mypair2.second<<endl;
//第三种 拷贝构造
pair<int,string> mypair3 = mypair;
cout<<mypair3.first<<" "<<mypair3.second<<endl;
2. map/multimap容器
2.1 map/multimap特性
map相对于set区别,map具有键值和实值,所有元素根据键值自动排序。pair的第一个元素被称为键值,第二个元素被称为实值。map也是以红黑树为底层实现机制


问题:我们通过map的迭代器可以修改map的键值吗?
答案是否定的,键值关系到容器内元素的排列规则,任意改变键值会破坏容器的排列规则,但是你可以改变实值
map和multimap的区别在于,map不允许相同的key存在,multimap允许相同key值存在
2.2 map常用API
map构造函数
map<T1,T2> mapTT;//默认构造
map(const map &mp);//拷贝构造
//map容器的模板参数 需要指定key类型 value 类型
map<int,string> mymap;//默认构造
map<int,string> mymap2(mymap);//拷贝构造
map赋值操作
map &operator=(const map &mp);//
swap(mp);//交换两个集合容器
map大小操作
int size();//返回容器中元素的数目
bool empty();//判断容器是否为空
map插入数据元素操作
pair<itertator,bool> insert(const pair<KEY_TYPE,VALUE_KEY) &val);//只有在val不存在时插入val.返回值是一个指向被插入元素的迭代器和一个描述是否插入的bool值
void insert(iterator beg,iterator end);//插入beg到end的元素到map中
iterator insert(iterator pos,const pair<KEY_TYPE,VALUE_KEY) &val);//插入val到pos后面,然后返回一个指向这个元素的迭代器
------------------------------------
pair<itertator,bool> insert(const pair<KEY_TYPE,VALUE_KEY) &val);
map<int,string> mapStu;
//第一种,通过Pair的方式插入对象
mapStu.insert(pair<int,string>(3,"小张"));
//第二种,通过pair的方式插入对象
mapStu.insert(make_pair(-1,"校长"));
//第三种 通过value_type的方式插入对象那个
mapStu.insert(map<int,string>::value_type(1,"小李"));
pair<map<int,string>::iterator,bool> ret = mapStu.insert(map<int,string>::value_type(1,"小红"));//插入成功or失败返回pair类型
if(ret.second){
cout<<"插入成功"<<endl;
}
else{
cout<<"插入失败"<<endl;
}
//第四种 通过数组的方式插入值
mapStu[3] = "小刘";
mapStu[5] = "小王";
mapStu[3] = "小钱";//这样重复的话,如果key值已经存在,就会修改容器指定key值元素的值
//如果你访问的key不存在,它会帮你把这个数据给你插进去
cout<<"key=20不存在,value:"<<mapStu[20]<<endl;//value为0
for(map<int,string>::itertaor it = mapStu.begin();it != mapStu.end();it++)
{
cout<<"key:"<<it->first<<" "<<"value:"<<it->second<<endl;
}//你会发现竟然多了一个key为20的元素!!!,所以mapStu[20]不只是读取,还是插入
cout<<endl;
map删除和查找
//删除
void erase(iterator pos);//erase()函数删除在pos位置的元素
void erase(iterator start,iterator end);//删除在start和end之间的元素
size_type erase(const KEY_TYPE &key);//删除那些值为key的所有元素
void print(map<int, int>& mymap){
for (map<int, int>::iterator it = mymap.begin(); it != mymap.end();it++){
cout << it->first << " " << it->second << " ";
}
cout << endl;
}
void test(){
map<int, int> mymap;
mymap.insert(make_pair(1, 2));
mymap.insert(make_pair(2, 3));
mymap.insert(make_pair(3, 4));
mymap.erase(2); //根据Key删除元素
print(mymap);
mymap.erase(mymap.begin()); //删除第一个元素
print(mymap);
mymap.erase(mymap.begin(),mymap.end()); // mymap.clear
cout << "map size:" << mymap.size() << endl;
//---------------------------------
//查找
iterator find(const KEY_TYPE &key);
iterator upper_bound(const KEY_TYPE &key);//upper_bound()函数返回一个迭代器,指向map中键值>key的第一个元素
iterator lower_bound(const KEY_TYPE &key)//lower_bound()函数返回一个迭代器,指向map中键值>=key的第一个元素
pair<map::iterator,map::itertaor> equal_range(const KEY_TYPE &key);//equal_range()函数返回两个迭代器,一个指向第一个键值为key的元素,另一个指向最后一个键值为key的元素
int count(KEY_TYPE keyElem);//返回容器中key为keyElem的对组个数。对map来说,要么是0,要么是1.对multimap来说,值可能大于1
map<int, int>::iterator pos = mymap.find(3);
if (pos == mymap.end()){
cout << "没有找到!" << endl;
}
else{
cout << "查找到:" << pos->first << " value:" << pos->second << endl;
}
cout << "---------------" << endl;
pos = mymap.lower_bound(2);
if (pos == mymap.end()){
cout << "没有找到!" << endl;
}
else{
cout << "查找到:" << pos->first << " value:" << pos->second << endl;
}
pos = mymap.upper_bound(2);
if (pos == mymap.end()){
cout << "没有找到!" << endl;
}
else{
cout << "查找到:" << pos->first << " value:" << pos->second << endl;
}
pair<map<int, int>::iterator, map<int, int>::iterator> pos2 = mymap.equal_range(2);
if (pos2.first == mymap.end()){ //第一个迭代器
cout << "没有找到!" << endl;
}
else{
cout << "查找到:" << pos2.first->first << " value:" << pos2.first->second << endl;
}
if (pos2.second == mymap.end()){ //第二个迭代器
cout << "没有找到!" << endl;
}
else{
cout << "查找到:" << pos2.second->first << " value:" << pos2.second->second << endl;
}
}
multimap练习
//multimap案例
//公司今天招聘了5个员工,5个员工进入公司之后,需要指派员工在哪个部门工作
//人员信息有:姓名 年龄 电话 工资等组成
//通过multimap进行信息的插入 保存 显示
//分部门显示员工信息 显示全部员工信息
#include <iostream>
#include <string>
#include <map>
#include <vector>
using namespace std;
#define SALE_DEPARTEMENT 1//销售部
#define DEVELOP_DEPARTMENT 2//开发部
#define FINACIAL_DEPARTMENT 3//财务部
class Employee
{
public:
string name;
int age;
string tele;
double salary;
};
//创建员工 5名
void Create_Employee(vector<Employee> &v){
string nameseed = "ABCDE";
for (int i = 0; i < 5; ++i)
{
Employee ep;
ep.name = "员工";
ep.name += nameseed[i];
ep.age = rand() % 30;
ep.salary = rand() % 10000 + 10000;
ep.tele = "+86-8888888";
v.push_back(ep);
}
}
//对员工指派部门
void Set_Ep_Group(vector<Employee> &v,multimap<int,Employee> & group){
for(vector<Employee>::iterator it = v.begin();it != v.end();it++){
cout<<"当前员工信息"<<endl;
cout<<"名字:"<<it->name<<" 年龄:"<<it->age<<" 工资:"<<it->salary<<" 电话:"<<it->tele<<endl;
int departmentID = -1;
while(true){
cout<<"请输入部门(1 销售部 2 开发部 3 财务部):"<<endl;
scanf("%d",&departmentID);
if (departmentID == SALE_DEPARTEMENT)
{
group.insert(make_pair(SALE_DEPARTEMENT,*it));
break;
}
else if(departmentID == DEVELOP_DEPARTMENT)
{
group.insert(make_pair(DEVELOP_DEPARTMENT,*it));
break;
}
else if(departmentID == FINACIAL_DEPARTMENT)
{
group.insert(make_pair(FINACIAL_DEPARTMENT,*it));
break;
}
else
{
cout<<"输入错误,请重新输入"<<endl;
}
}
}
}
//打印各部门员工信息
void Show_EP_Info(multimap<int,Employee> &group){
int departmentID = -1;
while(true){
cout<<"请输入要查看部门(1 销售部 2 开发部 3 财务部):"<<endl;
scanf("%d",&departmentID);
//验证输入的有效性
if (departmentID < 1 || departmentID > 3)
{
continue;
}
multimap<int,Employee>::itertaor ret = group.find(departmentID);
int count = group.count(departmentID);
while(count--){
cout<<"姓名:"<<pos->second.name <<" 年龄:"<<pos->second.age<<" 工资:"<<pos->second.salary<< "电话:"<<pos->second.tele<<endl;
pos++;
}
}
}
int main(int argc, char const *argv[])
{
vector<Employee> v;//放员工信息
Create_Employee(v);//创建员工
//员工分组
multimap<int,Employee> Epgroup;//存放分组后的员工信息
Set_Ep_Group(v,Epgroup);//员工分组
Show_EP_Info(Epgroup);
return 0;
}