STL常见容器(map/multimap容器)---C++

STL常见容器目录:

  • 8.map/ multimap容器
    • 8.1 map基本概念
    • 8.2 map构造和赋值
    • 8.3 map大小和交换
    • 8.4 map插入和删除
    • 8.5 map查找和统计
    • 8.6 map容器排序
      • 8.6.1 内置类型排序
      • 8.6.2 自定义类型排序
      • 8.6.3 自定义和内置类型混合排序
    • 8.7 实例
      • 8.7.1 案例描述
      • 8.7.2 实现步骤

在这里插入图片描述

8.map/ multimap容器

两者基本一致,除了以下区别:

map和multimap区别

  • map不允许容器中有重复key值元素;
  • multimap允许容器中有重复key值元素。
    注意:对于value值都可以重复

8.1 map基本概念

简介:

  • map中所有元素都是pair
  • pair中第一个元素为key(键值),起到索引作用,第二个元素为value(实值)(可以根据key值快速找到value值);
  • 所有元素都会根据元素的键值自动排序

本质:

  • map/multimap属于关联式容器,底层结构是用二叉树实现(同set容器)。

8.2 map构造和赋值

构造:

  • map<T1, T2> mp; //map默认构造函数:
  • map(const map &mp); //拷贝构造函数

赋值:

  • map& operator=(const map &mp); //重载等号操作符

总结:map中所有元素都是成对出现,插入数据时候要使用对组

8.3 map大小和交换

函数原型:

  • size(); //返回容器中元素的数目
  • empty(); //判断容器是否为空
  • swap(st); //交换两个集合容器

8.4 map插入和删除

函数原型:

  • insert(elem); //在容器中插入元素(四种方式)。
  • clear(); //清除所有元素
  • erase(pos); //删除pos迭代器所指的元素,返回下一个元素的迭代器。
  • erase(beg, end); //删除区间[beg,end)的所有元素 ,返回下一个元素的迭代器。
  • erase(key); //删除容器中值为key的元素

示例:

#include <map>//包含头文件(multimap头文件一样)

void Printmap(map<int, int>m)//按照key值排序(默认升序)
{
	for (map<int,int>::iterator it = m.begin(); it != m.end(); it++) {
		cout << "key=" << (*it).first << " value= " << it->second << endl;;
	}
	cout << endl;
}
void test01()
{
	map<int, int>m;

	//四种插入方式(多用前两种)
	m.insert(pair<int, int>(9, 90));//pair匿名对象
	m.insert(make_pair(8, 80));
	m.insert(map<int, int>::value_type(7, 70));
	m[6] = 60;//key=6,value=60
	Printmap(m);
cout << "方括号访问元素:" << m[9] << endl;//可利用[key]访问对于value值

	m.erase(7);//删除key=7的元素(若无相应key值,则不删除)
	Printmap(m);

}

在这里插入图片描述

8.5 map查找和统计

函数原型:

  • find(key); //查找key是否存在,若存在,返回该键的元素的迭代器若不存在,返回set.end();
  • count(key); //统计key的元素个数(map返回0或1;mutimap可能大于1

8.6 map容器排序

主要技术点:

  • 利用仿函数,可以改变排序规则。(默认升序)

8.6.1 内置类型排序

示例:

#include <map>

class MyCompare {
public:
	bool operator()(int v1, int v2) const 
	{
		return v1 > v2;//降序
	}
};

void test02()
{
	//默认从小到大排序
	//利用仿函数实现从大到小排序
	map<int, int, MyCompare> m;

	m.insert(make_pair(1, 10));
	m.insert(make_pair(2, 20));
	m.insert(make_pair(3, 30));
	m.insert(make_pair(4, 40));
	m.insert(make_pair(5, 50));

	for (map<int, int, MyCompare>::iterator it = m.begin(); it != m.end(); it++) {
		cout << "key:" << it->first << " value:" << it->second << endl;
	}
}

输出;

key:5 value:50
key:4 value:40
key:3 value:30
key:2 value:20
key:1 value:10

8.6.2 自定义类型排序

示例:

class Person
{
public:
	Person(string name, int age)
	{
		this->m_Name = name;
		this->m_Age = age;
	}

	string m_Name;
	int m_Age;

};
//仿函数
class MyCompare
{
public:

	bool operator()(const Person& v1, const Person& v2) const
	{
		//按照年龄进行排序  降序
		return v1.m_Age > v2.m_Age;
	}
};

void test03()
{

	//指定排序规则 
	map<Person,Person, MyCompare> m;//改变排序顺序需要在插入数据之前改变

	//插入自定义数据
	Person p1("刘备", 23);
	Person p2("关羽", 27);
	Person p3("张飞", 25);
	Person p4("赵云", 21);
	m.insert(make_pair(p1,p1));
	m.insert(make_pair(p2,p2));
	m.insert(make_pair(p3,p3));
	m.insert(make_pair(p4,p4));

	for (map<Person, Person, MyCompare>::iterator it = m.begin(); it != m.end(); it++) {
		cout << "姓名:" << it->second.m_Name << " 年龄:" << it->second.m_Age << endl;
	}
}

输出:

姓名:关羽 年龄:27
姓名:张飞 年龄:25
姓名:刘备 年龄:23
姓名:赵云 年龄:21

8.6.3 自定义和内置类型混合排序

示例:

#include <map>
class Person
{
public:
	Person(string name, int age)
	{
		this->m_Name = name;
		this->m_Age = age;
	}

	string m_Name;
	int m_Age;

};

void test04()
{
	map<int,Person> m;//若要改变排序顺序需要在插入数据之前改变
	//因为map排序是按照key值排序,此处key为整型,编译器可自行排序(升序)
	//降序参照8.6.1

	//插入自定义数据
	Person p1("刘备", 23);
	Person p2("关羽", 27);
	Person p3("张飞", 25);
	Person p4("赵云", 21);
	m.insert(make_pair(p1.m_Age,p1));
	m.insert(make_pair(p2.m_Age, p2));
	m.insert(make_pair(p3.m_Age, p3));
	m.insert(make_pair(p4.m_Age, p4));


	for (map<int, Person>::iterator it = m.begin(); it != m.end(); it++) {
		cout << "姓名:" << it->second.m_Name << " 年龄:" << it->second.m_Age << endl;
	}
}

输出:

姓名:赵云 年龄:21
姓名:刘备 年龄:23
姓名:张飞 年龄:25
姓名:关羽 年龄:27

总结:

  • 利用仿函数可以指定map容器的排序规则;
  • 对于自定义数据类型,map必须要指定排序规则,同set容器;

8.7 实例

8.7.1 案例描述

  • 公司今天招聘了10个员工(ABCDEFGHIJ),10名员工进入公司之后,需要指派员工在那个部门工作;
  • 员工信息有: 姓名 工资组成;部门分为:策划、美术、研发;
  • 随机给10名员工分配部门和工资;
  • 通过multimap进行信息的插入 key(部门编号) value(员工);
  • 分部门显示员工信息。

8.7.2 实现步骤

  1. 创建10名员工,放到vector中
  2. 遍历vector容器,取出每个员工,进行随机分组
  3. 分组后,将员工部门编号作为key,具体员工作为value,放入到multimap容器中
  4. 分部门显示员工信息

案例代码:

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

#define CEHUA  0//策划0 
#define MEISHU 1//美术1
#define YANFA  2//研发2
class Person
{
public:
	Person(string name, int wages)
	{
		this->m_name = name;
		this->m_wages = wages;
	}

	string m_name;
	int m_wages;//工资范围:10000-20000
};

//创建10名员工,放到vector中
void creat_person(vector<Person>&v)
{
	string nameSeed = "ABCDEFGHIJ";
	for (int i = 0; i < 10; i++)
	{
		string str ="员工";
		str += nameSeed[i];//形成“员工i”的字符串
		Person p(str, rand() % 10001 + 10000);//rand() % 10001 + 10000产生10000-20000
		v.push_back(p);
	}
}

//随机分组,员工部门编号作为key,具体员工作为value,放入到multimap容器中
void set_group(vector<Person>& v,multimap<int,Person>&m)
{
	for (int i = 0; i < v.size(); i++)
	{
		m.insert(make_pair(rand() % 3, v[i]));
	}
}

//分部门显示员工信息
void show_person(multimap<int, Person>& m)
{
	cout << "策划部门:" << endl;
	multimap<int, Person>::iterator pos = m.find(CEHUA);//找到第一个key=0的位置
	int count = m.count(CEHUA);//统计该部门人员数量
	for (int i = 0; pos != m.end() && i < count; i++, pos++)
	{ 
		//因为multimap容器按照key值自动排序
		// 所以从pos位置开始count个人员都是该部门的
		cout << "姓名:" << pos->second.m_name << " 工资:" << pos->second.m_wages << endl;
	}

	cout << "************************" << endl;
	cout << "美术部门:" << endl;
	 pos = m.find(MEISHU);
	 count = m.count(MEISHU);
	for (int i = 0; pos != m.end() && i < count; i++, pos++)
	{
		cout << "姓名:" << pos->second.m_name << " 工资:" << pos->second.m_wages << endl;
	}
	cout << "************************" << endl;

	cout << "研发部门:" << endl;
	pos = m.find(YANFA);
	count = m.count(YANFA);
	for (int i = 0; pos != m.end() && i < count; i++, pos++)
	{
		cout << "姓名:" << pos->second.m_name << " 工资:" << pos->second.m_wages << endl;
	}
}

int main()
{
	srand((unsigned int)time(NULL));
	vector<Person>v;
	multimap<int, Person> m;

	creat_person(v);
	set_group(v, m);
	
	show_person(m);

	system("pause");
	return 0;
}

某一次随机输出:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/425477.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Vue.js+SpringBoot开发高校实验室管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、研究内容2.1 实验室类型模块2.2 实验室模块2.3 实验管理模块2.4 实验设备模块2.5 实验订单模块 三、系统设计3.1 用例设计3.2 数据库设计 四、系统展示五、样例代码5.1 查询实验室设备5.2 实验放号5.3 实验预定 六、免责说明 一、摘…

基于springboot+vue的人格障碍诊断系统

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

云服务器租用哪家好?不要忽视第3点

注册资本&#xff1a;5亿元 权威认证&#xff1a;中央网信办云服务安全审查DJCP网络安全等级保护ITSS工信部云计算服务能力评估CSA STAR认证管理体系认证信息安全安全管理体系认证可信云服务认证可信云云主机等级评估5星 PCI-DSS支付卡行业数据安全认证 租哪家云服务器比较好&…

关于拖拽功能

文章目录 写在前面自己手动实现拖拽的demo技术细节&#xff1a;Js中拖拽(拉)事件&#xff08;drag 和 drop&#xff09;浏览器兼容性拖拽Api的介绍拖拽流程1.dragstart事件2.dragenter事件3.dragover事件4.drop事件(必须要dragover事件触发)5.dragend事件MDN关于拖拽的解析 相关…

latex中\documentclass[preprint,review,12pt]{elsarticle}的详细解释

在LaTeX中&#xff0c;\documentclass 是一个命令&#xff0c;用于指定文档所使用的文档类。文档类定义了文档的总体结构、格式和样式。elsarticle 是一个常用的文档类&#xff0c;它主要用于在Elsevier出版的期刊上提交论文。 详细解释 \documentclass[preprint,review,12pt…

基于Spring Boot+Vue的论坛网站

末尾获取源码作者介绍&#xff1a;大家好&#xff0c;我是墨韵&#xff0c;本人4年开发经验&#xff0c;专注定制项目开发 更多项目&#xff1a;CSDN主页YAML墨韵 学如逆水行舟&#xff0c;不进则退。学习如赶路&#xff0c;不能慢一步。 目录 一、项目简介 二、开发技术与环…

ViewModel 原理

在现代Android应用开发中&#xff0c;ViewModel是架构组件库的一个关键部分&#xff0c;它在提高应用的稳定性和性能方面发挥着重要作用。在这篇文章中&#xff0c;我们将深入探讨ViewModel的工作原理和最佳实践。 ViewModel简介 ViewModel是Android Jetpack架构组件的一部分…

2024.03.03 健身打卡第 14 天

成功只有一个——按照自己的方式&#xff0c;去度过人生 2024.03.03 健身打卡第 14 天

[Vulnhub]靶场 Red

kali:192.168.56.104 主机发现 arp-scan -l # arp-scan -l Interface: eth0, type: EN10MB, MAC: 00:0c:29:d2:e0:49, IPv4: 192.168.56.104 Starting arp-scan 1.10.0 with 256 hosts (https://github.com/royhills/arp-scan) 192.168.56.1 …

前端el-date-picker传递的日期格式不是自己想要的格式

解决方法&#xff1a; 添加format和value-format属性进行解决。 format“YYYY-MM-DD” value-format“YYYY-MM-DD” 注意&#xff1a;日期格式要用大写&#xff01;&#xff01;&#xff01;&#xff01;用小写会出现错误&#xff0c;不能回填选择的日期&#xff0c;会直接传入…

TCP/IP-常用网络协议自定义结构体

1、TCP/IP模型&#xff1a; 2、TCP/IP- 各层级网络协议&#xff08;从下往上&#xff09;&#xff1a; 1&#xff09;数据链路层&#xff1a; ARP: 地址解析协议&#xff0c;用IP地址获取MAC地址的协议&#xff0c;通过ip的地址获取mac地 …

带你快速初步了解Python字典

1.字典 定义多个数据一般使用列表&#xff0c;但是列表也存在一定的缺陷 若列表中有多个元素&#xff0c;想访问其中某个元素&#xff0c;比较不方便 定义字典的语法&#xff1a;{key1:value1, key2:value2, key3:value3......} 字典和列表习惯的使用场景&#xff1a; &qu…

PCSA时钟控制集成之时钟门控级别

这一部分描述了&#xff1a; • 时钟门控的级别。 • 实现最大效果的时钟门位置。 • 实现有效和高效时钟门控的集成方法。 时钟树是由时钟缓冲器构建的&#xff0c;这些缓冲器在时钟源&#xff08;时钟输入或PLL&#xff09;与时钟终端&#xff08;寄存器或RAM&#xff09…

软件测试项目实战,某购物车/测试点分析实战(详细步骤)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 第一步&#xff1…

SpringBoot整合OAuth2 实现单点登录 SSO

单点登录&#xff1a; SSO服务端和SSO客户端直接是通过授权以后发放Token的形式来访问受保护的资源相对于浏览器来说&#xff0c;业务系统是服务端&#xff0c;相对于SSO服务端来说&#xff0c;业务系统是客户端浏览器和业务系统之间通过会话正常访问不是每次浏览器请求都要去S…

Pyglet图形界面版2048游戏——详尽实现教程(上)

目录 Pyglet图形界面版2048游戏 一、色块展示 二、绘制标题 三、方阵色块 四、界面布局 五、键鼠操作 Pyglet图形界面版2048游戏 一、色块展示 准备好游戏数字的背景颜色&#xff0c;如以下12种&#xff1a; COLOR ((206, 194, 180, 255), (237, 229, 218, 255), (23…

详解算法的时间复杂度和空间复杂度!

目录 ​编辑 1. 算法效率 2. 时间复杂度 2.1 时间复杂度的概念 2.2 大O的表示渐进法 2.3 一个栗子 3. 空间复杂度 4. 常见复杂度对比 5. 完结散花 ​​​​​​​ 悟已往之不谏&#xff0c;知来者犹可追 创作不易&#xff0c;宝子们&#xff01;如果这篇文章对你们有…

C++之queue和deque

1、queue queue&#xff08;队列&#xff09;&#xff0c;一种数据结构&#xff0c;可以让某些数据结构的操作变得简单。队列&#xff08;queue&#xff09;最大的特点就是先进先出。就是说先放入queue容器的元素一定是要先出队列之后&#xff0c;比它后进入队列的元素才能够出…

二维码门楼牌管理系统技术服务详解:性能标准与反光膜要求

文章目录 前言一、二维码门楼牌管理系统技术服务的性能要求二、反光膜的性能标准三、制作完成的反光膜表层保护 前言 随着科技的快速发展&#xff0c;二维码门楼牌管理系统在现代化城市管理中扮演着越来越重要的角色。这一系统不仅提高了管理效率&#xff0c;还为市民提供了更…

Autosar Appl介绍

AUTOSAR架构中的应用层 AUTOSAR 应用层构成AUTOSAR 架构中的最顶层,被认为对所有车辆应用至关重要。AUTOSAR 标准使用“组件”概念指定应用层实现。 在谈论应用层实现时,应该考虑的三个最重要的部分是: AUTOSAR 应用软件组件这些组件的 AUTOSAR 端口AUTOSAR 端口接口 AUTOS…