【C++提高编程】map/ multimap 容器详解(附测试用例与结果图)
目录
- 1. map/ multimap容器
- 1.1 map基本概念
- 1.2 map构造和赋值
- 1.3 map大小和交换
- 1.4 map插入和删除
- 1.5 map查找和统计
- 1.6 map容器排序
- 1.7 案例-员工分组
- 1.7.1 案例描述
- 1.7.2 实现步骤
1. map/ multimap容器
1.1 map基本概念
简介:
- map中所有元素都是pair
- pair中第一个元素为key(键值),起到索引作用,第二个元素为value(实值)
- 所有元素都会根据元素的键值自动排序
本质:
- map/multimap属于关联式容器,底层结构是用二叉树实现。
优点:
- 可以根据key值快速找到value值
map和multimap区别:
- map不允许容器中有重复key值元素
- multimap允许容器中有重复key值元素
1.2 map构造和赋值
功能描述:
- 对map容器进行构造和赋值操作
函数原型:
构造:
map<T1, T2> mp;
//map默认构造函数:map(const map &mp);
//拷贝构造函数
赋值:
map& operator=(const map &mp);
//重载等号操作符
示例:
#include <map>void printMap(map<int,int>&m)
{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>(1, 10));m.insert(pair<int, int>(2, 20));m.insert(pair<int, int>(3, 30));printMap(m);map<int, int>m2(m); //拷贝构造printMap(m2);map<int, int>m3;m3 = m2; //赋值printMap(m3);
}int main() {test01();system("pause");return 0;
}
总结:map中所有元素都是成对出现,插入数据时候要使用对组
1.3 map大小和交换
功能描述:
- 统计map容器大小以及交换map容器
函数原型:
size();
//返回容器中元素的数目empty();
//判断容器是否为空swap(st);
//交换两个集合容器
示例:
#include <map>void printMap(map<int,int>&m)
{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>(1, 10));m.insert(pair<int, int>(2, 20));m.insert(pair<int, int>(3, 30));if (m.empty()){cout << "m为空" << endl;}else{cout << "m不为空" << endl;cout << "m的大小为: " << m.size() << endl;}
}//交换
void test02()
{map<int, int>m;m.insert(pair<int, int>(1, 10));m.insert(pair<int, int>(2, 20));m.insert(pair<int, int>(3, 30));map<int, int>m2;m2.insert(pair<int, int>(4, 100));m2.insert(pair<int, int>(5, 200));m2.insert(pair<int, int>(6, 300));cout << "交换前" << endl;printMap(m);printMap(m2);cout << "交换后" << endl;m.swap(m2);printMap(m);printMap(m2);
}int main() {test01();test02();system("pause");return 0;
}
总结:
- 统计大小 — size
- 判断是否为空 — empty
- 交换容器 — swap
1.4 map插入和删除
功能描述:
- map容器进行插入数据和删除数据
函数原型:
insert(elem);
//在容器中插入元素。clear();
//清除所有元素erase(pos);
//删除pos迭代器所指的元素,返回下一个元素的迭代器。erase(beg, end);
//删除区间[beg,end)的所有元素 ,返回下一个元素的迭代器。erase(key);
//删除容器中值为key的元素。
示例:
#include <map>void printMap(map<int,int>&m)
{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>(1, 10));//第二种插入方式m.insert(make_pair(2, 20));//第三种插入方式m.insert(map<int, int>::value_type(3, 30));//第四种插入方式m[4] = 40; printMap(m);//删除m.erase(m.begin());printMap(m);m.erase(3);printMap(m);//清空m.erase(m.begin(),m.end());m.clear();printMap(m);
}int main() {test01();system("pause");return 0;
}
总结:
- map插入方式很多,记住其一即可
- 插入 — insert
- 删除 — erase
- 清空 — clear
1.5 map查找和统计
功能描述:
- 对map容器进行查找数据以及统计数据
函数原型:
find(key);
//查找key是否存在,若存在,返回该键的元素的迭代器;若不存在,返回set.end();count(key);
//统计key的元素个数
示例:
#include <map>//查找和统计
void test01()
{map<int, int>m; m.insert(pair<int, int>(1, 10));m.insert(pair<int, int>(2, 20));m.insert(pair<int, int>(3, 30));//查找map<int, int>::iterator pos = m.find(3);if (pos != m.end()){cout << "找到了元素 key = " << (*pos).first << " value = " << (*pos).second << endl;}else{cout << "未找到元素" << endl;}//统计int num = m.count(3);cout << "num = " << num << endl;
}int main() {test01();system("pause");return 0;
}
总结:
- 查找 — find (返回的是迭代器)
- 统计 — count (对于map,结果为0或者1)
1.6 map容器排序
学习目标:
- map容器默认排序规则为 按照key值进行 从小到大排序,掌握如何改变排序规则
主要技术点:
- 利用仿函数,可以改变排序规则
示例:
#include <map>class MyCompare {
public:bool operator()(int v1, int v2) {return v1 > v2;}
};void test01()
{//默认从小到大排序//利用仿函数实现从大到小排序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;}
}
int main() {test01();system("pause");return 0;
}
总结:
- 利用仿函数可以指定map容器的排序规则
- 对于自定义数据类型,map必须要指定排序规则,同set容器
1.7 案例-员工分组
1.7.1 案例描述
- 公司今天招聘了10个员工(ABCDEFGHIJ),10名员工进入公司之后,需要指派员工在那个部门工作
- 员工信息有: 姓名 工资组成;部门分为:策划、美术、研发
- 随机给10名员工分配部门和工资
- 通过multimap进行信息的插入 key(部门编号) value(员工)
- 分部门显示员工信息
1.7.2 实现步骤
- 创建10名员工,放到vector中
- 遍历vector容器,取出每个员工,进行随机分组
- 分组后,将员工部门编号作为key,具体员工作为value,放入到multimap容器中
- 分部门显示员工信息
案例代码:
#include<iostream>
using namespace std;
#include <vector>
#include <string>
#include <map>
#include <ctime>/*
- 公司今天招聘了10个员工(ABCDEFGHIJ),10名员工进入公司之后,需要指派员工在那个部门工作
- 员工信息有: 姓名 工资组成;部门分为:策划、美术、研发
- 随机给10名员工分配部门和工资
- 通过multimap进行信息的插入 key(部门编号) value(员工)
- 分部门显示员工信息
*/#define CEHUA 0
#define MEISHU 1
#define YANFA 2class Worker
{
public:string m_Name;int m_Salary;
};void createWorker(vector<Worker>&v)
{string nameSeed = "ABCDEFGHIJ";for (int i = 0; i < 10; i++){Worker worker;worker.m_Name = "员工";worker.m_Name += nameSeed[i];worker.m_Salary = rand() % 10000 + 10000; // 10000 ~ 19999//将员工放入到容器中v.push_back(worker);}
}//员工分组
void setGroup(vector<Worker>&v,multimap<int,Worker>&m)
{for (vector<Worker>::iterator it = v.begin(); it != v.end(); it++){//产生随机部门编号int deptId = rand() % 3; // 0 1 2 //将员工插入到分组中//key部门编号,value具体员工m.insert(make_pair(deptId, *it));}
}void showWorkerByGourp(multimap<int,Worker>&m)
{// 0 A B C 1 D E 2 F G ...cout << "策划部门:" << endl;multimap<int,Worker>::iterator pos = m.find(CEHUA);int count = m.count(CEHUA); // 统计具体人数int index = 0;for (; pos != m.end() && index < count; pos++ , index++){cout << "姓名: " << pos->second.m_Name << " 工资: " << pos->second.m_Salary << endl;}cout << "----------------------" << endl;cout << "美术部门: " << endl;pos = m.find(MEISHU);count = m.count(MEISHU); // 统计具体人数index = 0;for (; pos != m.end() && index < count; pos++, index++){cout << "姓名: " << pos->second.m_Name << " 工资: " << pos->second.m_Salary << endl;}cout << "----------------------" << endl;cout << "研发部门: " << endl;pos = m.find(YANFA);count = m.count(YANFA); // 统计具体人数index = 0;for (; pos != m.end() && index < count; pos++, index++){cout << "姓名: " << pos->second.m_Name << " 工资: " << pos->second.m_Salary << endl;}}int main() {srand((unsigned int)time(NULL));//1、创建员工vector<Worker>vWorker;createWorker(vWorker);//2、员工分组multimap<int, Worker>mWorker;setGroup(vWorker, mWorker);//3、分组显示员工showWorkerByGourp(mWorker);测试//for (vector<Worker>::iterator it = vWorker.begin(); it != vWorker.end(); it++)//{// cout << "姓名: " << it->m_Name << " 工资: " << it->m_Salary << endl;//}system("pause");return 0;
}
总结:
- 当数据以键值对形式存在,可以考虑用map 或 multimap
相关文章:

【C++提高编程】map/ multimap 容器详解(附测试用例与结果图)
目录1. map/ multimap容器1.1 map基本概念1.2 map构造和赋值1.3 map大小和交换1.4 map插入和删除1.5 map查找和统计1.6 map容器排序1.7 案例-员工分组1.7.1 案例描述1.7.2 实现步骤1. map/ multimap容器 1.1 map基本概念 简介: map中所有元素都是pairpair中第一个…...
laravel操作redis和缓存操作
一:操作redis1:redis拓展安装composer require predis/predis或者你也可以通过 PECL 安装 PhpRedis PHP 扩展,安装方法比较复杂,个人不推荐2:配置redis在config/database.php文件中配置redis(1):单个redis配置redis > [client …...

目标检测论文阅读:GaFPN算法笔记
标题:Construct Effective Geometry Aware Feature Pyramid Network for Multi-Scale Object Detection 会议:AAAI2022 论文地址:https://ojs.aaai.org/index.php/AAAI/article/view/19932 文章目录Abstract1. Introduction2. Related Work2.…...

【转】Generative Pretrained Transformer
原文链接:https://www.cnblogs.com/yifanrensheng/p/13167796.html一、GPT简介1.1 背景目前大多数深度学习方法依靠大量的人工标注信息,这限制了在很多领域的应用。此外,即使在可获得相当大的监督语料情况下,以无监督学习的方式学…...

day34|343. 整数拆分、96.不同的二叉搜索树
343. 整数拆分 给定一个正整数 n ,将其拆分为 k 个 正整数 的和( k > 2 ),并使这些整数的乘积最大化。 返回 你可以获得的最大乘积 。 示例 1: 输入: n 2 输出: 1 解释: 2 1 1, 1 1 1。 示例 2: 输入: n 10 输出: 36 解…...

WeNet - 初识
文章目录关于 WeNet快速上手识别训练环境准备训练关于 WeNet Production First and Production Ready End-to-End Speech Recognition Toolkit github: https://github.com/wenet-e2e/wenet官方中文说明:https://github.com/wenet-e2e/wenet/blob/main/README_CN.md…...

为什么各个企业都在创建FAQ、常见问题页面?
常见问题解答页面是您可能已经为您的公司考虑过的东西,作为帮助客户回答有关您的产品和服务的常见问题的一种方式。但是您不知道最好的方法;肯定这只是一个问题清单吗?常见问题解答在整个购买过程中为客户提供支持,并减少客户需要与贵公司的联…...
【React-Router】路由传参,路由嵌套,手动导航,路由文件配置
文章目录React-RouterURL的hashHTML5的HistoryRouter的基本使用路由映射配置路由的嵌套路由配置和跳转Link和NavLink:手动路由的跳转路由参数传递Navigate导航Not Found页面配置路由的配置文件React-Router 前端路由是如何做到URL和内容进行映射呢?怎么…...
面向对象分析与设计(OOAD)
面向对象分析与设计(OOAD)概述人是怎么认识事物的分类与分层的两种思维问题域到解空间的映射软件生命周期要解决的问题三个一致性面向对象分析与设计过程对象从哪里来发现对象的方法组织对象结构职责是怎么来的分配职责的逻辑验证职责分配的合理性GRASP设…...
数据库调优
目录 硬件层面 操作系统层面 数据库层面 硬件层面 1.CPU(运算):48核CPU。 2.内存:96G-256G,跑3-4个实例。 3.disk(磁盘IO):机械盘:选SAS,数量越多越好。性能:SSD(高并发)>SAS(普通业务线上)>SATA(线下) 选SSD:使用SSD或者PCIe SSD设备,可提升上千倍的IOPS…...
OpenStack云平台搭建(3) | 部署Glance
目录 1、登录数据库授权 2、安装glance 3、测试一下 安装部署Glance镜像服务 Image Service 镜像服务:代号:Glance:为云平台虚拟机提供镜像服务,例如:上传镜像、删除镜像等。说明:镜像:磁盘…...
软件评测师考试总结
软件评测师是软考中级考试项,每年一次考试机会,2022年的是在11月份举行,具体事项需查看软考官网。 分享一下个人的备考经验,以及总结一下这个学习的过程,有需要的可以酌情参考。 一、方法策略 获取信息 官网&#x…...

小白系列Vite-Vue3-TypeScript:009-屏幕适配
上一篇我们介绍了ViteVue3TypeScript项目中mockjs的安装和配置。本篇我们来介绍屏幕适配方案,简单说来就是要最大程度上保证我们的界面在各种各样的终端设备上显示正常。通用的屏幕适配方案有两种:① 基于rem 适配(推荐,也是本篇要…...
查找企业微信聊天记录,会话存档有多重要
会话存档是基于企业微信API插口而开发设计的聊天记录查询专用工具。运用会话存档能不能找到误删除、到期的聊天记录呢?实际上能否通过会话存档找到企业微信中的聊天记录分两种状况,大家一起来看看吧:开启会话存档前的聊天记录没法找到和开启会…...

C语言经典编程题100例(1-20)
1、练习2-1 Programming in C is fun!本题要求编写程序,输出一个短句“Programming in C is fun!”。输入格式:本题目没有输入。输出格式:在一行中输出短句“Programming in C is fun!”。代码:#include<stdio.h> int main() {printf("Progra…...

小白系列Vite-Vue3-TypeScript:008-安装配置mock
上一篇我们介绍了ViteVue3TypeScript项目中axios的安装和配置,并手动封装了api。本篇我们来在上篇基础上介绍如何引入mock,并在本地模拟后台接口请求来达到本地测试的目的。在现在前后端分离的开发模式中,前端页面很多渲染的数据都需要通过ht…...

OnGUI Box 控件||Unity 3D OnGUI 常用控件
OnGUI Box 控件Unity 3D Box 控件用于在屏幕上绘制一个图形化的盒子。Box 控件中既可以显示文本内容,也可以绘制图片,或两者同时存在。GUIContent 和 GUIStyle 对于 Box 控件同样适用,既可以用来修饰 Box 控件的文本颜色,也可以用…...

shiro721——CVE-2019-12422
这两个漏洞主要区别在于Shiro550使⽤已知密钥碰撞,后者Shiro721是使⽤ 登录后rememberMe {value}去爆破正确的key值 进⽽反序列化,对⽐Shiro550条件只要有 ⾜够密钥库 (条件⽐较低)、Shiro721需要登录(要求⽐较⾼鸡肋 …...

爬虫JS逆向思路 - - 扣JS(data解密)
网络上几千块都学不到的JS逆向思路这里全都有👏🏻👏🏻👏🏻 本系列持续更新中,三连关注不迷路👌🏻 干货满满不看后悔👍👍👍 ❌注意…...

Android 进阶——Framework 核心之Binder 相关预备理论(一)
文章大纲引言一、进程的内存空间和进程隔离二、Linux 系统内存的用户空间和内核空间1、用户空间(User Space)2、内核空间(Kernel Space)三、Linux IPC 原理1、内核态和用户态2、IPC 步骤四、内核模块和驱动五、Binder1、Binder IP…...
《Playwright:微软的自动化测试工具详解》
Playwright 简介:声明内容来自网络,将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具,支持 Chrome、Firefox、Safari 等主流浏览器,提供多语言 API(Python、JavaScript、Java、.NET)。它的特点包括&a…...

《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》
在注意力分散、内容高度同质化的时代,情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现,消费者对内容的“有感”程度,正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中࿰…...

Python实现prophet 理论及参数优化
文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候,写过一篇简单实现,后期随着对该模型的深入研究,本次记录涉及到prophet 的公式以及参数调优,从公式可以更直观…...

DBAPI如何优雅的获取单条数据
API如何优雅的获取单条数据 案例一 对于查询类API,查询的是单条数据,比如根据主键ID查询用户信息,sql如下: select id, name, age from user where id #{id}API默认返回的数据格式是多条的,如下: {&qu…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
Java多线程实现之Thread类深度解析
Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...

USB Over IP专用硬件的5个特点
USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中,从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备(如专用硬件设备),从而消除了直接物理连接的需要。USB over IP的…...
JavaScript 数据类型详解
JavaScript 数据类型详解 JavaScript 数据类型分为 原始类型(Primitive) 和 对象类型(Object) 两大类,共 8 种(ES11): 一、原始类型(7种) 1. undefined 定…...
C语言中提供的第三方库之哈希表实现
一. 简介 前面一篇文章简单学习了C语言中第三方库(uthash库)提供对哈希表的操作,文章如下: C语言中提供的第三方库uthash常用接口-CSDN博客 本文简单学习一下第三方库 uthash库对哈希表的操作。 二. uthash库哈希表操作示例 u…...

【Post-process】【VBA】ETABS VBA FrameObj.GetNameList and write to EXCEL
ETABS API实战:导出框架元素数据到Excel 在结构工程师的日常工作中,经常需要从ETABS模型中提取框架元素信息进行后续分析。手动复制粘贴不仅耗时,还容易出错。今天我们来用简单的VBA代码实现自动化导出。 🎯 我们要实现什么? 一键点击,就能将ETABS中所有框架元素的基…...