Day 28 C++ (映射)map 容器 / multimap 容器 (多重映射)

文章目录

  • map (映射)
      • 定义
          • 注意
          • 优点
      • map构造和赋值
          • 构造
          • 赋值
          • 示例
      • map大小和交换
          • 函数原型
          • 示例
      • map插入和删除
          • 函数原型
          • 四种插入方式
          • 示例
      • map查找和统计
          • 函数原型
          • 示例
      • map容器排序
  • multimap 容器 (多重映射)
      • 定义
      • 特点
      • 和map的区别
      • 示例

map (映射)

定义

C++中的map是一种关联容器,它提供了一种键-值(key-value)对的存储方式。map容器中的元素是按照键的顺序进行排序的,并且每个键都唯一。通过使用键来访问其相应的值,我们可以在O(log n)的时间复杂度内进行快速的查找、插入和删除操作。

map与set类似,但不同之处在于map存储的是键值对(key-value pair),而set只存储单个元素。每个键值对在map中被视为一个元素,由键(key)和值(value)组成。键用于唯一标识元素,值则是与键相关联的数据。

注意
  • map中所有元素都是pair
  • pair中第一个元素为key(键值),起到索引作用,第二个元素为value(实值)
  • map 是一个有序容器,所有元素都会根据元素的键值自动排序
  • 每个键只能在 map 中唯一出现。如果插入一个已存在的键,那么新的值会取代旧的值。
优点
  • 快速查找
    map基于红黑树实现,这使得在大量数据情况下,查找操作具有较好的时间复杂度(平均为O(log n))。因此,可以根据key值快速找到value值
  • 有序性
    map以键的顺序进行排序,这意味着通过map迭代器遍历时可以按照键的有序性进行操作。这对于需要按照键的顺序访问数据的场景非常方便。
  • 唯一键
    map中每个键都是唯一的,这意味着相同的键只会出现一次。当需要确保数据中的键是唯一的时,map提供了一种有效的数据结构来实现这一点。
  • 稳定性
    由于map基于红黑树实现,它对插入和删除操作的平均时间复杂度为O(log n),这使得在频繁更新数据的场景中也能保持较好的性能稳定性。

map构造和赋值

构造
  • map<T1, T2> mp; //map默认构造函数:
  • map(const map &mp); //拷贝构造函数
赋值
  • map& operator=(const map &mp); //重载等号操作符
示例

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

#include <iostream>
#include <map>int main() {// 创建一个空的mapstd::map<int, std::string> mp;// 使用insert插入元素mp.insert(std::make_pair(1, "apple"));mp.insert(std::make_pair(2, "banana"));mp.insert(std::make_pair(3, "orange"));// 输出map的元素for (const auto& pair : mp) {std::cout << pair.first << ": " << pair.second << std::endl;}// 使用拷贝构造函数创建一个新的mapstd::map<int, std::string> copyMap(mp);// 使用等号操作符进行赋值std::map<int, std::string> assignedMap;assignedMap = mp;return 0;
}

输出
1: apple
2: banana
3: orange


map大小和交换

函数原型
  • size(); //返回容器中元素的数目
  • empty(); //判断容器是否为空
  • swap(st); //交换两个集合容器
示例
#include <iostream>
#include <map>int main() {// 创建一个mapstd::map<int, std::string> mp;// 插入一些元素mp.insert(std::make_pair(1, "apple"));mp.insert(std::make_pair(2, "banana"));mp.insert(std::make_pair(3, "orange"));// 获取容器中元素的数目std::cout << "Size: " << mp.size() << std::endl;// 判断容器是否为空if (mp.empty()) {std::cout << "Map is empty" << std::endl;} else {std::cout << "Map is not empty" << std::endl;}// 创建另一个mapstd::map<int, std::string> anotherMap;anotherMap.insert(std::make_pair(4, "grape"));anotherMap.insert(std::make_pair(5, "kiwi"));// 交换两个mapmp.swap(anotherMap);// 输出交换后的结果std::cout << "Map after swap:" << std::endl;for (const auto& pair : mp) {std::cout << pair.first << ": " << pair.second << std::endl;}return 0;
}

输出结果
Size: 3
Map is not empty
Map after swap:
4: grape
5: kiwi

分析
在上述示例中,我们首先创建了一个map<int, string>,并插入了几个键值对。然后我们使用size()函数获取容器中元素的数目,并使用empty()函数判断容器是否为空。

接下来,我们创建了另一个map anotherMap,并插入了一些元素。然后使用swap()函数交换了两个map的内容,将原来的mp与anotherMap进行了交换。最后,我们遍历并输出了交换后的map的元素。

需要注意的是,swap()函数会直接交换两个map的内容,而不是创建副本或者复制元素。


map插入和删除

函数原型
  • insert(elem); //在容器中插入元素。
  • clear(); //清除所有元素
  • erase(pos); //删除pos迭代器所指的元素,返回下一个元素的迭代器。
  • erase(beg, end); //删除区间[beg,end)的所有元素 ,返回下一个元素的迭代器。
  • erase(key); //删除容器中值为key的元素。
四种插入方式
  • 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;

注意

map<int, int>::value_type(3, 30) 是一个创建 map 中键值对的方法。它使用了 map 的嵌套类型 value_type,表示键值对的类型。注意,map<int, int>::value_typepair<const Key, T> 的别名,其中 Key 是键的类型,T 是值的类型。

value_type 是 map 类的内部类型,表示键值对的类型。在这里,map<int, int>::value_type 表示 pair<const int, int>,即键为 const int 类型,值为 int 类型的键值对。

这种方式仅适用于 C++03 标准及之前的版本。从 C++11 标准开始,我们可以直接使用简化的插入语法,如 m.insert({3, 30})

示例
#include <iostream>
#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;
}int main() {//插入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);return 0;
}

在上述示例中,我们首先创建了一个map<int, int>,然后使用四种不同的插入方式向map中插入了一些元素,并使用printMap函数输出map的内容。

接下来,我们使用erase函数删除了第一个元素和键为3的元素,并再次使用printMap函数输出了更新后的map。

最后,我们使用clear函数清空了整个map,并再次使用printMap函数输出了清空后的map。

需要注意的是,map中的元素是按照键的顺序进行排序的,而且键必须是唯一的。同时,使用erase函数删除元素时可以指定要删除的元素的位置或者键值。


map查找和统计

函数原型
  • find(key); //查找key是否存在,若存在,返回该键的元素的迭代器;否则返回set.end();
  • count(key); //统计key的元素个数 (对于map,结果为0或者1, 最多一个不重复)
示例
#include <iostream>
#include <map>int main() {std::map<int, int> m;// 插入元素m.insert(std::pair<int, int>(1, 10));m.insert(std::pair<int, int>(2, 20));m.insert(std::pair<int, int>(3, 30));m.insert(std::pair<int, int>(4, 40));// 使用 find 函数查找键为 3 的元素std::map<int, int>::iterator it = m.find(3);if (it != m.end()) {std::cout << "键为 3 的元素存在,值为 " << it->second << std::endl;} else {std::cout << "键为 3 的元素不存在" << std::endl;}// 使用 count 函数统计键为 4 的元素个数int count = m.count(4);std::cout << "键为 4 的元素个数为 " << count << std::endl;// 查找一个不存在的键it = m.find(5);if (it != m.end()) {std::cout << "键为 5 的元素存在,值为 " << it->second << std::endl;} else {std::cout << "键为 5 的元素不存在" << std::endl;}return 0;
}

输出
键为 3 的元素存在,值为 30
键为 4 的元素个数为 1
键为 5 的元素不存在

在上述示例中,我们首先创建了一个map<int, int>并向其中插入了几个元素。然后,我们使用find(key)函数来查找键为 3 的元素,并根据返回的迭代器判断该元素是否存在。

接下来,我们使用count(key)函数统计键为 4 的元素的个数。

最后,我们使用find(key)函数查找一个不存在的键 5,并根据返回的迭代器判断该元素是否存在。

需要注意的是,对于count(key)函数来说,由于map容器的特性,它的返回值要么是 0(表示键不存在),要么是 1(表示键存在)。因为map 中每个键都是唯一的。


map容器排序

  • map容器默认排序规则为 按照key值进行 从小到大排序
  • 利用仿函数可以指定map容器的排序规则
  • 对于自定义数据类型,map必须要指定排序规则,同set容器

重载 operator() 运算符是定义一个仿函数的必要条件。实际上,仿函数就是一个对象,在使用仿函数时,我们可以像调用函数一样使用它进行计算。在 C++ 中,仿函数可以重载多个运算符,但重载 operator() 运算符是最常见的情况,因为它使得对象可以被像函数一样调用,并且提供了比较接近函数调用的语法。除了重载 operator() 运算符外,仿函数还可以根据需要重载其他运算符,例如 operator+operator- 等运算符,以实现特定的功能。

示例:

#include <iostream>
#include <map>// 自定义仿函数类来指定排序规则
struct MyComparator {bool operator()(int a, int b) const {return a > b; // 从大到小排序}
};int main() {std::map<int, std::string, MyComparator> m; // 使用自定义排序规则的 map// 向 map 中插入元素m.insert(std::pair<int, std::string>(3, "Alice"));m.insert(std::pair<int, std::string>(1, "Bob"));m.insert(std::pair<int, std::string>(4, "Charlie"));m.insert(std::pair<int, std::string>(2, "David"));// 打印按照自定义排序规则排序后的结果for (const auto& pair : m) {std::cout << pair.first << ": " << pair.second << std::endl;}return 0;
}

输出
4: Charlie
3: Alice
2: David
1: Bob

在上述示例中,我们定义了一个名为 MyComparator 的仿函数类,用于指定排序规则。该仿函数类重载了 operator() 运算符,其中通过返回 a > b 来实现从大到小排序。

然后,我们创建了一个类型为 map<int, string> 的 map 容器,并将自定义的 MyComparator 类作为第三个模板参数传递给 map,以指定排序规则为从大到小。

接下来,我们向 map 中插入了几个元素,并通过遍历 map 打印出按照自定义排序规则排序后的结果。

需要注意的是,在使用自定义排序规则时,关键是要将该规则作为 map 的第三个模板参数进行指定,以告诉 map 使用自定义排序规则。

multimap 容器 (多重映射)

定义

multimap 是 C++ STL 中的一个关联容器,它提供了一种键值对的存储方式,允许一个键对应多个值。multimap 容器中的元素按照键的自然顺序进行排序,并且可以有重复的键。

特点

可以有重复的键。
键和值可以是任意数据类型。
键值对是按照键的自然顺序进行排序的。
提供了高效的插入、查找和删除操作

和map的区别

multimap 可以有多个相同的键,map不行,其他二者几乎一致

示例

#include <iostream>
#include <map>int main() {std::multimap<int, std::string> mm;// 插入键值对mm.insert(std::pair<int, std::string>(3, "Alice"));mm.insert(std::pair<int, std::string>(1, "Bob"));mm.insert(std::pair<int, std::string>(2, "Charlie"));mm.insert(std::pair<int, std::string>(3, "David"));// 遍历 multimapfor (const auto& pair : mm) {std::cout << pair.first << ": " << pair.second << std::endl;}return 0;
}

输出
1: Bob
2: Charlie
3: Alice
3: David

在上述示例中,我们创建了一个 multimap<int, string> 类型的 multimap 容器,并向其中插入了几个键值对。其中,键是 int 类型,值是 string 类型。

然后,我们通过遍历 multimap 容器,打印出所有的键值对。

需要注意的是,由于 multimap 容器允许有重复的键,因此在遍历时,可能会输出相同键的多个值。

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在跨境电子商务客户支持中使用AI的几种方法

OpenAI&#xff0c;ChatGPT等&#xff0c;AI正在快速发展。今天的人工智能比以往任何时候都更智能、更细致、更准确。高性能的客户支持团队为任何电子商务业务提供了许多好处。这些优势包括更高的销售额、更好的保留率、更高的忠诚度和信任度、更高的认知度和品牌知名度、更好的…

【总结】Javaweb和Java项目的比较

&#x1f384;欢迎来到边境矢梦的csdn博文&#x1f384; &#x1f384;本文主要梳理Javaweb中的关键点和需要注意的地方&#x1f384; &#x1f308;我是边境矢梦&#xff0c;一个正在为秋招和算法竞赛做准备的学生&#x1f308; &#x1f386;喜欢的朋友可以关注一下&#x1f…

docker 安装hive

记录一下使用docker快速搭建部署hive环境 目录 写在前面 步骤 安装docker 安装docker安装docker-compose配置docker国内镜像源&#xff08;可选&#xff09; 安装git & 配置github部署Hive docker-hive开始部署 使用Hive命令行收尾工作 安装vi、lrzsz关闭相关命令 END…

常见设计模式

概念 设计模式是怎么解决问题的一种方案 常见的设计模式 单例模式 概念&#xff1a;保证一个类仅有一个实例&#xff0c;并提供一个访问它的全局访问点。 应用&#xff1a;项目封装个websocket用于大屏&#xff0c;redux&#xff0c;vuex都应用了单例模式的思想&#xff1b…

通过MATLAB自动产生Hamming编译码的verilog实现,包含testbench

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 1. 原理 1.1 编码规则 1.2 错误检测和纠正 2. 实现过程 2.1 编码过程 2.2 解码过程 3. 应用领域 3.1 数字通信 3.2 存储系统 3.3 ECC内存 3.4 数据传输 5.算法完整程序工程 1.算法…

robotframework+selenium 进行webui页面自动化测试

robotframework其实就是一个自动化的框架&#xff0c;想要进行什么样的自动化测试&#xff0c;就需要在这框架上添加相应的库文件&#xff0c;而用于webui页面自动化测试的就是selenium库. 关于robotframework框架的搭建我这里就不说了&#xff0c;今天就给大家根据一个登录的实…

wsl2安装mysql环境

安装完mysql后通过如下命令启动mysql service mysql start 会显示如下错误&#xff1a; mysql: unrecognized service 实际上上面显示的错误是由于mysql没有启动成功造成的 我们要想办法成功启动mysql才可以 1.通过如下操作就可以跳过密码直接进入mysql环境 2.如果想找到my…

边写代码边学习之LSTM

1. 什么是LSTM 长短期记忆网络 LSTM&#xff08;long short-term memory&#xff09;是 RNN 的一种变体&#xff0c;其核心概念在于细胞状态以及“门”结构。细胞状态相当于信息传输的路径&#xff0c;让信息能在序列连中传递下去。你可以将其看作网络的“记忆”。理论上讲&a…

LeetCode_03Java_1572. 矩阵对角线元素的和

给你一个正方形矩阵 mat&#xff0c;请你返回矩阵对角线元素的和。 请你返回在矩阵主对角线上的元素和副对角线上且不在主对角线上元素的和。 输入&#xff1a;mat [[1,2,3],[4,5,6],[7,8,9]] 输出&#xff1a;25 解释&#xff1a;对角线的和为&#xff1a;1 5 9 3 7 2…

kube-prometheus 使用 blackbox-exporter 进行icmp 监控

安装kube-prometheus 后默认在monitoring namespace中有创建 blackbox-exporter deployment。但默认没有icmp的module配置&#xff0c;无法执行ping探测。因为即使有icmp module&#xff0c;默认配置也是无法执行ping探测的&#xff08;这篇文章要解决的就是这个问题&#xff0…

mybatis-plus逻辑删除的坑

一旦在逻辑字段上加了TableLogic逻辑删除的配置&#xff0c;并且使用mybatis-plus自带的方法时&#xff08;如果自己用xml写SQL不会出现下面的情况&#xff09; 查询、修改时会自动排除逻辑删除的数据 当使用mybatis-plus自带的查询方法时&#xff0c;就不用每次查询的时候跟…

Elasticsearch同时使用should和must

问题及解决方法 must和should组合查询&#xff0c;should失效。使用must嵌套查询&#xff0c;将should组成的bool查询包含在其中一个must查询中。 SearchRequest request new SearchRequest(); request.indices("function_log");SearchSourceBuilder sourceBuilde…

数字化时代,选择商业智能BI解决80%数据问题

数据是需要有人来照料、培养的&#xff0c;如果企业没有完善的数据治理方案&#xff0c;就很难保障数据的质量&#xff0c;进而导致数据无法利用&#xff0c;让这些辛苦积累的数据失去了价值。 数据治理目标 数据从业务活动中产生&#xff0c;也会深刻影响到业务本身。 对于…

GrapeCity Documents for Excel, .NET Crack

GrapeCity Documents for Excel, .NET 增加了对双面打印的支持。 GcExcel.NET支持PrintOutOptions类中的Duplex枚举&#xff0c;以启用/禁用页面上的双面打印。 枚举中有四个选项&#xff0c;用户可以相应地使用它们来打印工作簿&#xff1a; 双面打印。Default表示打印机的默认…

Docker高级篇_DockerFile

目录 DockerFile简介构建DockerFile构建过程解析Docker执行Dockerfile的大致流程 DockerFile常用保留字指令FROMMAINTAINERRUNEXPOSEWORKDIRUSERENVVOLUMEADDCOPYCMDENTRYPOINT案例使用虚悬镜像 Docker微服务 DockerFile简介 Dockerfile是用来构建Docker镜像的文本文件&#x…

基于STM32微控制器的物联网(IoT)节点设计与实现

基于STM32微控制器的物联网(IoT)节点的设计和实现。我们讨论物联网节点的基本概念和功能,并详细介绍了STM32微控制器的特点和优势。然后,我们将探讨如何使用STM32开发环境和相关的硬件模块来设计和实现一个完整的物联网节点。最后,我们将提供一个示例代码,展示如何在STM3…

【CheatSheet】Python、R、Julia数据科学编程极简入门

《Python、R、Julia数据科学编程极简入门》PDF版&#xff0c;是我和小伙伴一起整理的备忘清单&#xff0c;帮助大家10分钟快速入门数据科学编程。 另外&#xff0c;最近 TIOBE 公布了 2023 年 8 月的编程语言排行榜。 Julia 在本月榜单中实现历史性突破&#xff0c;成功跻身 …

(一)创建型设计模式:3、建造者模式(Builder Pattern)

目录 1、建造者模式含义 2、建造者模式的讲解 3、使用C实现建造者模式的实例 4、建造者模式的优缺点 5、建造者模式VS工厂模式 1、建造者模式含义 The intent of the Builder design pattern is to separate the construction of a complex object from its representatio…

opencv基础45-图像金字塔01-高斯金字塔cv2.pyrDown()

什么是图像金字塔&#xff1f; 图像金字塔&#xff08;Image> Pyramid&#xff09;是一种用于多尺度图像处理和分析的技术&#xff0c;它通过构建一系列不同分辨率的图像&#xff0c;从而使得图像可以在不同尺度下进行处理和分析。图像金字塔在计算机视觉、图像处理和计算机…

Vue实现详细界面里面有一个列表

目录 Vue实现详细界面里面有一个列表 理一下思路&#xff1a; 效果如下&#xff1a; 1、 主页面正常写 2、详细界面(重点) 3、详细界面里面的列表(重点) 要点&#xff1a; Vue实现详细界面里面有一个列表 理一下思路&#xff1a; 1、首先需要这条数据的主键id&#xff…