ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

C++STL map/multimap容器

2021-05-26 23:02:31  阅读:184  来源: 互联网

标签:map multimap insert STL make vector pair include


1、map/multimap容器简介

  • map 的特性是所有的元素都会根据元素的键值自动排序。map所有元素都是pair(对组),同时拥有实值和键值,pair的第一元素被认为是键值。
  • 不能通过map的迭代器改变map的键值,因为map的键值关系到map元素的排序规则,任意改变map的键值将会破坏map组织。如果想修改map的实值是可以的
  • map和list拥有相同的某些性质,在对容器进行插入或删除操作时,除了删除元素外其他所有元素的迭代器依然有效。
  • multimap和map的操作类似,唯一区别是multimap键值可以重复。
  • map和multimap都是以红黑树为底层实现机制。

2、API

/*******************************map**********************************/
map<T1,T2> mapT;//map默认构造函数
map(const map& mp);//拷贝构造函数
/*******************************map赋值操作****************************/
map& operator=(const map& mp);//重载等号操作符
swap(mp);//交换两个集合容器
/*******************************map大小操作****************************/
size();//返回容器中元素的数目
empty();//判断容器是否为空
/*******************************插入数据元素**************************/
map<int,string> m;
//第一种:通过pair方式插入对象
m.insert(pair<int,string>(3,"小张"));
//第二种:通过pair方式插入对象
m.insert(make_pair(1,"小明"));
//第三种:通过value_type方式插入对象
m.insert(map<int,string>::value_type(2,"小李"));
//第四种:通过数组方式插入值
m[3]="小刘";
/*******************************删除操作**************************/
clear();//删除所有元素
erase(pos);//删除pos迭代器所指向的元素,返回下一个元素的迭代器
erase(beg,end);//删除区间[beg,end)的所有元素,返回下一个元素的迭代器
erase(keyElem);//删除容器中key为keyElem的对组
/*******************************查找操作**************************/
find(key);//查找键key是否存在。若存在返回该键的元素的迭代器;若不存在,返回map.end()
count(keyElem);//返回容器中key为keyElem的对组个数。对于map来说要么0要么1.对于multimap来说可能大于1
lower_bound(keyElem);//返回第一个key>=keyElem元素的迭代器
upper_bound(keyElem);//返回第一个key>keyElem元素的迭代器
equal_range(keyElem);//返回容器中key与keyElem相等的上下限的两个迭代器

3、使用

insert、find

#include<iostream>
#include<map>
#include<string>
#include<algorithm>
using namespace std;
void test()
{
	map<int, string> m;
	m.insert(pair<int, string>(9527, "星爷"));//第一种插入方式
	m.insert(make_pair(10010, "联通"));//第二种插入方式(推荐!!!)
	m.insert(map<int, string>::value_type(10086, "移动"));//第三种插入方式
	m[10000] = "电信";//第四种插入方式(在访问map数据时推荐使用!!!!!)
	for_each(m.begin(),m.end(),[](pair<int,string> val){
		cout << val.first << "  " << val.second << endl;
	});
	cout << "***********************************************************" << endl;
	//m[10]寻找key为10的值
	//但是如果容器中没有key为10,使用m[10]会创建一个key为10实值为空的对组
	//如果容器中有key为10,那么m[10]代表key=10的值
	//建议务必确保所需访问的元素存在
	cout << m[10] << endl;
	cout << m[9527] << endl;
	cout << "***********************************************************" << endl;
	//若不能确定key值是否存在,可以先行判断
	map<int, string>::const_iterator mit;
	mit = m.find(10);
	if (mit == m.end()) {
		cout << "未找到!" << endl;
	}
	else {
		cout << m[10] << endl;
	}
}

在这里插入图片描述

案例1:map和vector配合使用

LoL职业联赛:有4个战队,随机抽签出场,请打印出场顺序

#include<numeric>//极少的算法
#include<stdlib.h>
#include<time.h>
#include<iostream>
#include<map>
#include<string>
#include<algorithm>

using namespace std;
void test{
    //设置种子
    srand(time(NULL));
    //战队容器(战队编号,战队名称)
    map<int,string> m;
    m.insert(make_pair(1,"RNG"));
    m.insert(make_pair(2,"IG"));
    m.insert(make_pair(3,"WE"));
    m.insert(make_pair(4,"EDG"));
    
    //使用vector存放战队编号
    v.push_back(1);
    v.push_back(2);
    v.push_back(3);
    v.push_back(4);
    //随机抽签(洗牌),打乱容器元素顺序
    random_shuffle(v.begin(),v.end());
    //随机出场
    for_each(v.begin(),v.end(),[=](int val){
        cout<<m[val]<<"战队出场!"<<endl;//val就是m容器中的key值
    });
}
//multimap允许key相同,map不允许key相同
void test2()
{
    //战队容器(战队编号,战队名称)
    map<int,string> m;
    m.insert(make_pair(1,"RNG"));
    m.insert(make_pair(1,"IG"));
    cout<<m[1]<<endl;//RNG
    cout<<m.count(1)<<endl;//1
    
    //战队容器(战队编号,战队名称)
	multimap<int, string> mm;
	mm.insert(make_pair(1, "RNG"));
	mm.insert(make_pair(1, "IG"));
	//cout << mm[1] << endl;//error,multimap没有[]运算符
	cout << mm.count(1) << endl;//2
}

案例2:multimap案例

公司招聘5名员工,需要指派他们到各部门工作。人员信息有:姓名、年龄、电话、工资等,通过multimap进行信息的插入、保存、显示。分部门显示员工信息,显示全部员工信息。

#include<iostream>
#include<vector>
#include<map>
#include<string>
#include<algorithm>
using namespace std;

class Person {
public:
	string name;
	int age;
	Person(string n, int a){
		name = n;
		age = a;
	}
};
void createPerson(vector<Person>& v)
{
	v.push_back(Person("员工A", 21));
	v.push_back(Person("员工B", 25));
	v.push_back(Person("员工C", 24));
	v.push_back(Person("员工D", 27));
	v.push_back(Person("员工E", 26));

}
void createDepartmentToPerson(multimap<int, Person>& m, vector<Person>& v)
{
	for (int i = 0; i < v.size(); i++){
		int op=0;
		cout << "请输入" << v[i].name << "的部门号(1,2,3):";
		cin >> op;
		switch (op){
		case 1:
			m.insert(make_pair(1, v[i])); break;
		case 2:
			m.insert(make_pair(2, v[i])); break;
		case 3:
			m.insert(make_pair(3, v[i])); break;
		}
	}
}
void printDepartment(multimap<int, Person> m, int op)
{
	string depart;
	switch (op){
	case 1:
		depart = "技术部"; break;
	case 2:
		depart = "测试部"; break;
	case 3:
		depart = "后勤部"; break;
	}

	multimap<int, Person>::const_iterator ret;
	ret = m.find(op);//判断查找的部门号是否存在
	if (ret != m.end()){
		cout << depart << "的员工有:" << endl;
		int count = m.count(op);//统计部门号重复的次数
		for (int i = 0; i < count; i++){
			cout << (*ret).second.name << ",年龄" << (*ret).second.age << endl;
			++ret;//multimap容器已经按键值排序,所以键值相同的数据紧挨着
		}
	}
	else{
		cout << depart << "没有员工!" << endl;
	}
}
int main()
{
	vector<Person> v;//存放员工信息
	createPerson(v);//创建员工
	multimap<int, Person> m;//存放部门号和员工信息
	createDepartmentToPerson(m, v);//创建部门到员工的映射
	printDepartment(m, 1);//打印部门员工
	printDepartment(m, 2);
	printDepartment(m, 3);

	return 0;
}

在这里插入图片描述

4、vector、deque、list、set、map应用场景

  • vector的使用场景:比如软件历史操作记录的存储,我们经常要查看历史记录,比如上一次记录,上上次记录,但却不会去删除记录,因为记录是事实的描述。
  • deque的使用场景:比如排队购票系统,对排队者的存储可以采用deque,支持头端的快速移除,尾端的快速添加。如果采用vector,则头端移除时,会移动大量数据,速度漫。
  • vector和deque的比较:①vector.at()比deque.at()效率高,比如vector.at(0)是固定的,deque的开始位置却是不固定的;②如果有大量释放操作的话,vector花的时间更少,这跟二者的内部实现有关;③deque支持头部的快速插入和删除,这是deque的优点。
  • list的使用场景:比如公交车乘客的存储,随时可能有乘客下车,支持频繁的不确定位置元素的移除插入。
  • set的使用场景:比如对手机游戏的个人得分记录的存储,存储要求从高分到低分的顺序排列。
  • map的使用场景:比如按ID号存储十万个用户,想要快速通过ID查找对应的用户。二叉树的查找效率就体现出来了。如果是vector容器,最坏的情况可能要遍历完整个容器才能找到该用户。

标签:map,multimap,insert,STL,make,vector,pair,include
来源: https://blog.csdn.net/qq_45311905/article/details/117307500

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有