当前位置: 首页 > news >正文

C++的map / multimap容器

一、介绍

        在C++的map / multimap容器中,所有的元素均是pair类型(有关pair类型可以参考我之前写的 《C++的set / multiset容器》的3.2中有介绍到)。

        每对pair的第一个元素被称为关键字key,第二个元素被称为value。因此,map的元素也被称为键值对

        将元素插入map / multimap后,元素会根据关键字的排序规则自动排序

二、数据结构

        map / multimap容器均属于关联式容器,底层使用平衡二叉树 / 红黑树实现。

三、map与multimap的区别

        map与multimap的区别在于是否可以出现重复的key

map不允许同一个map中出现重复key
multimap允许同一个map中出现重复ke


        由于二者之间除此以外并无差别,因此下文例子均基于map容器的使用示例。

四、map的使用

        map在使用前,请包含头文件#include<map>。此外,为了便于观察示例结果,以下示例均使用自己编写的printMap函数打印map所有键值对信息。

//打印map所有键值对
void printMap(map<int, char> &m) {//判空if (m.empty()) {cout << "The map is empty now." << endl;return;}for (map<int, char>::iterator it = m.begin(); it != m.end(); it++) {cout << "<" << it->first << ", " << it->second << ">" << endl;}
}

4.1 map初始化

        map的初始化可以使用构造函数=运算符实现:

声明解释
map<T1, T2> m;

构造函数,初始化一个空map

m的关键字key类型为T1值value的类型为T2

map<T1, T2> m(map<T1, T2> m1);拷贝构造函数,用m1初始化m
operator=(map<T1, T2> m1)

重载的=运算符,

有关重载运算符可以看我之前写的《C++重载运算符》

map<int, char> m0;//初始化一个空map,key为int类型,value为char类型
map<int, char> m1(m0);//拷贝构造函数
map<int, char> m2 = m0;//使用重载的等号运算符

4.2 map容量与大小

声明解释
empty()判断map是否为空
size()返回map中键值对数目
map<int, char> m0;
for (int i = 0; i < 10; i++) {//i作为key,小写字母作为valuem0.insert(pair<int, char>(i, 'a' + i));
}
//cout << "m0 : " << endl; printMap(m0);cout << boolalpha << m0.empty() << endl;//false
cout << m0.size() << endl;//10

         程序的执行结果如下所示:

4.3 map交换元素

声明解释
swap(map<T1, T2> m1)交换当前map与m1的全部元素
map<int, char> m0;
map<int, char> m1;
for (int i = 0; i < 10; i++) {//i作为key,小写字母作为m0的valuem0.insert(pair<int, char>(i, 'a' + i));//i作为key,大写字母作为m1的valuem1.insert(pair<int, char>(i, 'A' + i));
}cout << "Before Swap : " << endl;
cout << "m0 : " << endl; printMap(m0);
cout << "m1 : " << endl; printMap(m1);m0.swap(m1);//交换
cout << "-------------------分割线--------------------" << endl;
cout << "After. Swap : " << endl;
cout << "m0 : " << endl; printMap(m0);
cout << "m1 : " << endl; printMap(m1);

         程序执行结果如下所示:

4.4 map插入元素

声明解释
insert(pair<T1, T2>(key, value))将键值对<key, value>插入到map
map<int, char> m0;
for (int i = 0; i < 10; i++) {//i作为key,小写字母作为m0的valuem0.insert(pair<int, char>(i, 'a' + i));
}
cout << "m0 : " << endl; printMap(m0);

         程序运行结果如下所示:

4.5 map删除元素

声明解释
erase(pos)

删除迭代器pos指向的那个元素,

返回下一个元素的迭代器

erase(begin, end)

删除迭代器pos指向的那个元素,

返回下一个元素的迭代器

erase(key)

删除map中关键字key的元素

(如果是multimap,则删除关键字key全部元素)

clear()清除全部元素

4.5.1 erase(pos)示例

map<int, char> m0;
for (int i = 0; i < 10; i++) {//i作为key,小写字母作为m0的valuem0.insert(pair<int, char>(i, 'a' + i));
}
cout << "m0 : " << endl; printMap(m0);//erase(m0.begin+1)
map<int, char>::iterator begin = m0.begin();
begin++;
m0.erase(begin);
cout << "After erase(m0.begin+1) , m0 : " << endl; printMap(m0);

        程序运行结果如下所示:

4.5.2 erase(begin, end)示例

map<int, char> m0;
for (int i = 0; i < 10; i++) {//i作为key,小写字母作为m0的valuem0.insert(pair<int, char>(i, 'a' + i));
}
cout << "m0 : " << endl; printMap(m0);//erase(m0.begin+1, end-2)
map<int, char>::iterator begin = m0.begin();
map<int, char>::iterator end = m0.end();
begin++;
end--; end--;
m0.erase(begin, end);
cout << "After erase(m0.begin+1, end-2) , m0 : " << endl; printMap(m0);

         程序运行结果如下所示:

4.5.3 erase(key)示例

        为了便于测试删除的是关键字为key全部元素,此示例采用multimap:

multimap<int, char> m0;
for (int i = 0; i < 10; i++) {//i作为key,小写字母作为m0的valuem0.insert(pair<int, char>(i, 'a' + i));
}
//插入<0, 'A'> <0, 'B'> <0, 'C'>
for (int i = 0; i < 3; i++) {m0.insert(pair<int, char>(0, 'A' + i));
}
cout << "m0 : " << endl; printMap(m0);//erase(0)
m0.erase(0);
cout << "After erase(0) , m0 : " << endl; printMap(m0);

        程序运行结果如下所示:

4.5.4 clear()示例

map<int, char> m0;
for (int i = 0; i < 10; i++) {//i作为key,小写字母作为m0的valuem0.insert(pair<int, char>(i, 'a' + i));
}
cout << "m0 : " << endl; printMap(m0);//clear()
m0.clear();
cout << "After clear() , m0 : " << endl; printMap(m0);

         程序运行结果如下所示:

4.6 map查找元素

声明解释
find(key)

返回map中关键字key第一个元素的迭代器

如果没找到,返回end()

multimap<int, char> m0;
for (int i = 0; i < 10; i++) {//i作为key,小写字母作为m0的valuem0.insert(pair<int, char>(i, 'a' + i));
}
//插入<0, 'A'> <0, 'B'> <0, 'C'>
for (int i = 0; i < 3; i++) {m0.insert(pair<int, char>(0, 'A' + i));
}
cout << "m0 : " << endl; printMap(m0);//找到key为0的第一个元素的迭代器
multimap<int, char>::iterator it = m0.find(0);
cout << "it->second : " << it->second << endl;

         程序运行结果如下所示:

4.7 map统计指定元素个数

声明解释
count(key)统计map中关键字key的元素个数
multimap<int, char> m0;
for (int i = 0; i < 10; i++) {//i作为key,小写字母作为m0的valuem0.insert(pair<int, char>(i, 'a' + i));
}
//插入<0, 'A'> <0, 'B'> <0, 'C'>
for (int i = 0; i < 3; i++) {m0.insert(pair<int, char>(0, 'A' + i));
}
cout << "m0 : " << endl; printMap(m0);//统计key为0的元素个数
cout << "m0.count(0) : " << m0.count(0) << endl;

        程序运行结果如下所示:

4.8 map自定义排序规则

        map和set类似,一样可以通过仿函数指定自己的排序规则。(有关set容器可以看我之前写的文章《C++的set / multiset容器》)

        下面给出一个示例便于直观理解。为了便于说明问题,以下类中的成员权限均设置为public。首先我们先自定义一个关键字类MyKey

class MyKey {
public://优先级:id1 > id2int id1;int id2;
};

        接下来我们给出指定排序规则仿函数

//仿函数:自定义排序规则
class MyKeyCompare {
public:bool operator()(MyKey k1, MyKey k2) const {if (k1.id1 == k2.id1) {//如果二者id1相等,则比较id2return k1.id2 < k2.id2;}else {return k1.id1 < k2.id1;}}
};

        在定义语句的第三个泛型中指定仿函数,元素在插入后将自动按照仿函数的规则进行排序,在主函数进行测试,打印map的全部元素信息:

//打印map所有元素信息的函数
void printMp(map<MyKey, string, MyKeyCompare> &mp) {for (map<MyKey, string>::iterator it = mp.begin(); it != mp.end(); it++) {cout << "id1为" << it->first.id1 << ", ";cout << "id2为" << it->first.id2 << ", ";cout << "名为" << it->second << endl;}
}//主函数
int main() {map<MyKey, string, MyKeyCompare> mp;mp.insert(pair<MyKey, string>(MyKey(0, 1), "A"));mp.insert(pair<MyKey, string>(MyKey(2, 1), "B"));mp.insert(pair<MyKey, string>(MyKey(1, 6), "C"));mp.insert(pair<MyKey, string>(MyKey(0, 4), "D"));mp.insert(pair<MyKey, string>(MyKey(1, 1), "E"));printMp(mp);return 0;
}

        程序的执行结果如下所示:

         从上述结果中观察可以看出,各个元素已经按照先id1后id2的规则进行自动排序了。

相关文章:

C++的map / multimap容器

一、介绍 在C的map / multimap容器中&#xff0c;所有的元素均是pair类型&#xff08;有关pair类型可以参考我之前写的 《C的set / multiset容器》的3.2中有介绍到&#xff09;。 每对pair的第一个元素被称为关键字key&#xff0c;第二个元素被称为值value。因此&#xff0c;ma…...

双向链表 -- 详细理解和实现

欢迎光顾我的homepage 前言 双向链表是一种带头双向循环的链表。在双向链表中&#xff0c;首先存在着一个头结点&#xff1b;其次每个节点有指向下一个节点的指针next 和指向上一个节点的指针prev &#xff1b…...

WebGIS面试题

文章目录 1. 前端1.1. 选择器的优先级1.2. CSS 中它的布局有哪些&#xff1f;1.3. CSS3 的新特性1.4. CSS 的两种盒子模型1.5. CSS 的伪元素选择器和伪类选择器有哪些&#xff1f;1.6. ES6 的新特性1.7. 谈谈你对 promise 的理解1.8. 简单说一下原型链1.9. 简单说一下深浅拷贝1…...

代码随想录算法训练营:21/60

非科班学习算法day21 | LeetCode669:修剪二叉搜索树 &#xff0c;Leetcode108:将有序数组转换为二叉搜索树 &#xff0c;Leetcode538:把二叉搜索树转换为累加树 介绍 包含LC的两道题目&#xff0c;还有相应概念的补充。 相关图解和更多版本&#xff1a; 代码随想录 (progra…...

数据结构——二叉树之c语言实现堆与堆排序

目录 前言&#xff1a; 1.二叉树的概念及结构 1.1 特殊的二叉树 1.2 二叉树的存储结构 1.顺序存储 2.链式存储 2. 二叉树的顺序结构及实现 2.1 堆的概念 ​编辑 2.2 堆的创建 3.堆的实现 3.1 堆的初始化和销毁 初始化&#xff1a; 销毁&#xff1a; 插入&…...

#数据结构 链表

单向链表 1. 概念 单向链表 单向循环链表 双向链表 双向循环链表 解决&#xff1a;长度固定的问题&#xff0c;插入和删除麻烦的问题 1、逻辑结构&#xff1a; 线性结构 2、存储结构&#xff1a; 链式存储 链表就是将 结点 用链串起来的线性表&#xff0c;链就是 结点 中的…...

单片机软件架构连载(4)-结构体

枚举、指针、结构体&#xff0c;我愿称为C语言"三板斧"。 用人话来讲&#xff0c;几乎所有c语言高阶编程&#xff0c;都离不开这这3个知识点的应用。 今天站在实际产品常用的角度&#xff0c;给大家讲一下结构体。 1.结构体概念 结构体可以用来构建更复杂的数据结…...

工厂方法模式在金融业务中的应用及其框架实现

引言 工厂方法模式&#xff08;Factory Method Pattern&#xff09;是一种创建型设计模式&#xff0c;它定义了一个创建对象的接口&#xff0c;但由子类决定实例化哪一个类。工厂方法模式使得类的实例化延迟到子类。在金融业务中&#xff0c;工厂方法模式可以用于创建不同类型…...

python库(6):Pygments库

1 Pygments介绍 在软件开发和文档编写中&#xff0c;代码的可读性是至关重要的一环。无论是在博客文章、技术文档还是教程中&#xff0c;通过代码高亮可以使程序代码更加清晰和易于理解。而在Python世界中&#xff0c;Pygments库就是这样一个强大的工具&#xff0c;它能够将各…...

金斗云 HKMP智慧商业软件 任意用户创建漏洞复现

0x01 产品简介 金斗云智慧商业软件是一款功能强大、易于使用的智慧管理系统,通过智能化的管理工具,帮助企业实现高效经营、优化流程、降低成本,并提升客户体验。无论是珠宝门店、4S店还是其他零售、服务行业,金斗云都能提供量身定制的解决方案,助力企业实现数字化转型和智…...

前端JS特效第24集:jquery css3实现瀑布流照片墙特效

jquery css3实现瀑布流照片墙特效&#xff0c;先来看看效果&#xff1a; 部分核心的代码如下(全部代码在文章末尾)&#xff1a; <!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8" /> <title>jquerycss3实现瀑…...

区块链论文速读A会-ISSTA 2023(2/2)如何检测DeFi协议中的价格操纵漏洞

Conference&#xff1a;ACM SIGSOFT International Symposium on Software Testing and Analysis (ISSTA) CCF level&#xff1a;CCF A Categories&#xff1a;Software Engineering/System Software/Programming Languages Year&#xff1a;2023 第1~5篇区块链文章 请点击此…...

权力之望怎么下载客户端 权力之望一键下载

《权力之望》是一款由NX3 Games开发、Smilegate发行的多人在线动作MMORPG游戏。这款游戏最大的特点是高度的自由度和丰富的角色定制选项。我们在游戏中不仅可以自由更换武器&#xff0c;而且游戏还提供了54种能力和60多种职业选择&#xff0c;让我们可以根据自己的游戏风格和喜…...

Oracle PL/SQL 循环批量执行存储过程

1. 查询存储过程 根据数据字典USER_OBJECTS查询出所有存储过程。 2. 动态拼接字符串&#xff08;参数等&#xff09; 根据数据字典USER_ARGUMENTS动态拼接参数。 3. 动态执行 利用EXECUTE IMMEDIATE动态执行无名块。 4. 输出执行信息 利用DBMS_OUTPUT.PUT_LINE输出执行成功与…...

kafka 生产者

生产者 生产者负责创建消息&#xff0c;然后将其投递到Kafka中。 负载均衡 轮询策略。随机策略。按照 key 进行hash。 Kafka 的默认分区策略&#xff1a;如果指定了 key&#xff0c;key 相同的消息会发送到同一个分区&#xff08;分区有序&#xff09;&#xff1b;如果没有…...

Powershell 获取电脑保存的所有wifi密码

一. 知识点 netsh wlan show profiles 用于显示计算机上已保存的无线网络配置文件 Measure-Object 用于统计数量 [PSCustomObject]{ } 用于创建Powershell对象 [math]::Round 四舍五入 Write-Progress 显示进度条 二. 代码 只能获取中文Windows操作系统的wifi密码如果想获取…...

golang结合neo4j实现权限功能设计

neo4j 是非关系型数据库之图形数据库&#xff0c;这里不再赘述。 传统关系数据库基于rbac实现权限, user ---- role ------permission,加上中间表共5张表。 如果再添上部门的概念&#xff1a;用户属于部门&#xff0c;部门拥有 角色&#xff0c;则又多了一层&#xff1a; user-…...

java 参数传递(尤其注意参数是对象的情况)

8大基本数据类型为 值传递 类和数组为 引用传递&#xff0c;传递的是地址 但是要注意虽然类是引用传递&#xff0c;但是要注意&#xff0c;调用方法是新开一个栈 因此如果进行p null或者 Person p new Person()等语句&#xff0c;要格外注意&#xff1a; 如果主函数再次输出…...

拼音字符串相似度

拼音字符串相似度 拼音字符串相似度介绍参考代码**编辑距离****余弦相似度****Jaccard相似度**参考文档拼音字符串相似度 介绍 拼音相似度是指在拼音转换后,两个拼音字符串之间的相似程度。常用的拼音相似度度量方法包括编辑距离、余弦相似度和 Jaccard 相似度等。 编辑距离…...

如何创建一个基本的Mojolicious Web应用:探索Perl的现代Web框架

如何创建一个基本的Mojolicious Web应用&#xff1a;探索Perl的现代Web框架 Mojolicious是一个用Perl编写的简单、优雅的Web开发框架&#xff0c;它提供了一套丰富的工具和方法&#xff0c;让开发者能够快速构建高性能的Web应用。本文将详细介绍如何创建一个基本的Mojolicious…...

变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析

一、变量声明设计&#xff1a;let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性&#xff0c;这种设计体现了语言的核心哲学。以下是深度解析&#xff1a; 1.1 设计理念剖析 安全优先原则&#xff1a;默认不可变强制开发者明确声明意图 let x 5; …...

在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:

在 HarmonyOS 应用开发中&#xff0c;手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力&#xff0c;既支持点击、长按、拖拽等基础单一手势的精细控制&#xff0c;也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档&#xff0c…...

23-Oracle 23 ai 区块链表(Blockchain Table)

小伙伴有没有在金融强合规的领域中遇见&#xff0c;必须要保持数据不可变&#xff0c;管理员都无法修改和留痕的要求。比如医疗的电子病历中&#xff0c;影像检查检验结果不可篡改行的&#xff0c;药品追溯过程中数据只可插入无法删除的特性需求&#xff1b;登录日志、修改日志…...

Linux简单的操作

ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...

python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)

更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...

css的定位(position)详解:相对定位 绝对定位 固定定位

在 CSS 中&#xff0c;元素的定位通过 position 属性控制&#xff0c;共有 5 种定位模式&#xff1a;static&#xff08;静态定位&#xff09;、relative&#xff08;相对定位&#xff09;、absolute&#xff08;绝对定位&#xff09;、fixed&#xff08;固定定位&#xff09;和…...

k8s业务程序联调工具-KtConnect

概述 原理 工具作用是建立了一个从本地到集群的单向VPN&#xff0c;根据VPN原理&#xff0c;打通两个内网必然需要借助一个公共中继节点&#xff0c;ktconnect工具巧妙的利用k8s原生的portforward能力&#xff0c;简化了建立连接的过程&#xff0c;apiserver间接起到了中继节…...

docker 部署发现spring.profiles.active 问题

报错&#xff1a; org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...

在Ubuntu24上采用Wine打开SourceInsight

1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...

Go 语言并发编程基础:无缓冲与有缓冲通道

在上一章节中&#xff0c;我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道&#xff0c;它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好&#xff0…...