c++笔记 容器 map

一、map容器的特点

1、所有元素都会根据元素的键值自动排序

2、所有的元素都是pair,同时拥有键值实值。 第一个参数:键值 第二个参数:实值

3、map容器的键值唯一 不可变 实值 可变。

二、map容器的插入、遍历 

void test()
{
	/*
	map/multimap常用API
	map构造函数
	map<T1, T2> mapTT;//map默认构造函数:
	map(const map &mp);//拷贝构造函数
	map赋值操作
	map& operator=(const map &mp);//重载等号操作符
	swap(mp);//交换两个集合容器
	map大小操作
	size();//返回容器中元素的数目
	empty();//判断容器是否为空
	map插入数据元素操作
	map.insert(...); //往容器插入元素,返回pair<iterator,bool>
	map<int, string> mapStu;
	//第一种 通过pair的方式插入对象
	mapStu.insert(pair<int, string>(3, "小张"));
	// 第二种 通过pair的方式插入对象
	mapStu.inset(make_pair(‐1, "校长"));
	// 第三种 通过value_type的方式插入对象
	mapStu.insert(map<int, string>::value_type(1, "小李"));
	// 第四种 通过数组的方式插入值
	mapStu[3] = "小刘";
	mapStu[5] = "小王";
	map删除操作
	clear();//删除所有元素
	erase(pos);//删除pos迭代器所指的元素,返回下一个元素的迭代器。
	erase(beg,end);//删除区间[beg,end)的所有元素 ,返回下一个元素的迭代器。
	erase(keyElem);//删除容器中key为keyElem的对组。
	map查找操作
	find(key);//查找键key是否存在,若存在,返回该键的元素的迭代器;/若不存在,返回m
	ap.end();
	count(keyElem);//返回容器中key为keyElem的对组个数。对map来说,要么是0,要么是
	对multimap来说,值可能大于1。
	lower_bound(keyElem);//返回第一个key>=keyElem元素的迭代器。
	upper_bound(keyElem);//返回第一个key>keyElem元素的迭代器。
	equal_range(keyElem);//返回容器中key与keyElem相等的上下限的两个迭代器。
	*/
	
	//存放9527‐‐"星爷" 10086‐"移动" 10010‐‐"联通" 10000‐‐"电信"
			//int为键值的类型 string为实值的类型
	map<int, string> m;
	//第1种:
	m.insert(pair<int, string>(9527, "星爷"));
	//第2种:(推荐)
	m.insert(make_pair(10086, "移动"));
	//第3种:
	m.insert(map<int, string>::value_type(10010, "联通"));
	//第4种:读map容器数据的时候 推荐
	m[10000] = "电信";//m.insert(make_pair(10000,"电信"));
	//m[10] 寻找key为10的实值
	//但是:如果容器中没有key为10 使用m[10] 会创建一个key为10实值为空的 对组
	//如果容器中有key为10 那么m[10]代表key=10的实值
	//建议:10是存在的
	cout << m[10] << endl;
	myPrintMap01(m);
	#if 0
		 for_each(m.begin(), m.end(), [](pair<int, string> val) {
		 cout << "key=" << val.first << ", value=" << val.second << endl;
		 });
	#endif
	//只想查看key==9527 的实值 (保证key是存在的)
	cout << m[9527] << endl;//"星爷"
	cout << m[10010] << endl;//"联通"
	//如果不能确定key值是否存在
	map<int, string>::const_iterator ret;
	ret = m.find(10086);
	if (ret == m.end())
	{
		cout << "未找到相关节点" << endl;
			 
	}
	else
	{
	 //ret代表的是key=10086的对组的迭代器
		cout << "找到相关节点:key=" << (*ret).first << ", value=" << (*ret).second << endl;
	}

}

 三、multimap案例

公司今天招聘了 5 个员工,5 名员工进入公司之后,需要指派员工在那个部门工作 人员信息有: 姓名 年龄 电话 工资等组成 通过 Multimap 进行信息的插入 保存 显示 分部门显示员工信息 显示全部员工信息

#include<iostream>
#include<map>
#include<algorithm>
#include<time.h>
#include<string>
#include<vector>
using namespace std;
#define SALE_DEPATMENT 1 //销售部门
#define DEVELOP_DEPATMENT 2 //研发部门
#define FINACIAL_DEPATMENT 3 //财务部门
#define ALL_DEPATMENT 4 //所有部门
class Person {
public:
	string name;
	int age;
	double salary;
	string tele;
};
//创建五个员工
void createperson(vector<Person> worker)
{
	string tmp = "ABCDE";
	for (int i = 0; i < tmp.size(); ++i)
	{
		Person p;
		p.name = "员工";
		p.name += tmp[i];
		p.age = rand() % 30 + 20;
		p.salary = rand() % 20000 + 10000;
		p.tele = "010-8888888";
		worker.push_back(p);
	}
}

//5 名员工分配到不同的部门
void Personbygroup(vector<Person> &list, multimap<int, Person> &plist)
{
	int operate = -1;//用户的操作
	for (vector<Person>::iterator it; it != list.end(); it++)
	{
		cout << "当前员工信息" << endl;
		cout << "姓名:" << it->name << "年龄:" << it->age << "工资"
			<< it->salary << "电话" << it->tele << endl;
		cout << "请对该员工进行部门分配(1 销售部门, 2 研发部门, 3 财务部门):" << endl;
		cin >> operate;
		while (true)
		{
			if (operate == SALE_DEPATMENT) {
				plist.insert(make_pair(SALE_DEPATMENT, *it));
				break;
			}
			else if (operate == DEVELOP_DEPATMENT) {
				plist.insert(make_pair(DEVELOP_DEPATMENT, *it));
				break;
			}
			else if (operate == FINACIAL_DEPATMENT) {
				plist.insert(make_pair(FINACIAL_DEPATMENT, *it));
				break;
			}
			else {
				cout << "您的输入有误,请重新输入(1 销售部门, 2 研发部门, 3 财务部门):" << endl;
				cin >> operate;
			}
		}
	}
	cout << "员工部门分配完毕!" << endl;
	cout << "***********************************************************" << endl;
}
//打印员工信息
void Printlist(multimap<int, Person> &mlist , int myoperate)
{
	if (myoperate == ALL_DEPATMENT) {
		for (multimap<int, Person>::iterator it = mlist.begin(); it != mlist.end(); it++)
		{
			cout << "姓名:" << it->second.name << " 年龄:" << it->second.age 
				<< " 工资:" << it->second.salary << " 电话:" << it->second.tele << endl;
		}
		return;
	}
	multimap<int, Person>::iterator it = mlist.find(myoperate);
	int depatCount = mlist.count(myoperate);
	int num = 0;
	if (it != mlist.end()) {
		while (it != mlist.end() && num < depatCount) {
			cout << "姓名:" << it->second.name << " 年龄:" << it->second.age \
				<< " 工资:" << it->second.salary << "  电话:" << it->second.tele << endl;
			it++;
			num++;
		}
	}
}
//根据用户操作显示不同部门的人员列表
void ShowPersonList(multimap<int, Person>& plist, int myoperate) {
	switch (myoperate)
	{
		case SALE_DEPATMENT:
			Printlist(plist, SALE_DEPATMENT);
			break;
		case DEVELOP_DEPATMENT:
			Printlist(plist, DEVELOP_DEPATMENT);
			break;
		case FINACIAL_DEPATMENT:
			Printlist(plist, FINACIAL_DEPATMENT);
			break;
		case ALL_DEPATMENT:
			Printlist(plist, ALL_DEPATMENT);
			break;
	}
}
//用户操作菜单
void PersonMenue(multimap<int, Person>& plist) {
	int flag = -1;
	int isexit = 0;
	while (true) {
		cout << "请输入您的操作((1 销售部门, 2 研发部门, 3 财务部门, 4所有部门, 0 退出):" << endl;
		cin >> flag;
		switch (flag)
		{
		case SALE_DEPATMENT:
			ShowPersonList(plist, SALE_DEPATMENT);
			break;
		case DEVELOP_DEPATMENT:
			ShowPersonList(plist, DEVELOP_DEPATMENT);
			break;
		case FINACIAL_DEPATMENT:
			ShowPersonList(plist, FINACIAL_DEPATMENT);
			break;
		case ALL_DEPATMENT:
			ShowPersonList(plist, ALL_DEPATMENT);
			break;
		case 0:
			isexit = 1;
			break;
		default:
			cout << "您的输入有误,请重新输入!" << endl;
			break;
		}
		if (isexit == 1) {
			break;
		}
	}
}
                                         
int main()
{
	vector<Person> vlist; //创建的 5 个员工 未分组
	multimap<int, Person> plist; //保存分组后员工信息
	//创建 5 个员工
	createperson(vlist);
	//5 名员工分配到不同的部门
	Personbygroup(vlist, plist);
	//根据用户输入显示不同部门员工信息列表 或者 显示全部员工的信息列表
	PersonMenue(plist);
	system("pause");
	return 0;
}

四、STL 容器使用时机

vector 的使用场景:比如软件历史操作记录的存储,我们经常要查看历史记录, 比如上一次的记录,上上次的记录,但却不会去删除记录,因为记录是事实的描 述。

deque 的使用场景:比如排队购票系统,对排队者的存储可以采用 deque, 支持头端的快速移除,尾端的快速添加。如果采用 vector,则头端移除时,会移动 大量的数据,速度慢。

vector 与 deque 的比较: 一:vector.at()比 deque.at() 效率高,比如 vector.at(0)是固定的,deque 的开始位置 却是不固定的。

二:如 果有大量释放操作的话,vector 花的时间更少,这跟二者的内部实现有关。

三: deque 支持头部的快速插入与快速移除,这是 deque 的优点。 list 的使用场景: 比如公交车乘客的存储,随时可能有乘客下车,支持频繁的不确实位置元素的移除 插入。

set 的使用场景:比如对手机游戏的个人得分记录的存储,存储要求从高 分到低分的顺序排列。 map 的使用场景:比如按 ID 号存储十万个用户,想要 快速要通过 ID 查找对应的用户。二叉树的查找效率,这时就体现出来了。如果是 vector 容器,最坏的情况下可能要遍历完整个容器才能找到该用户。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值