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

《21天学通C++》(第二十章)STL映射类(map和multimap)

为什么需要mapmultimap
1.查找高效: 映射类允许通过键快速查找对应的值,这对于需要频繁查找特定元素的场景非常适合。
2.自动排序: 会自动根据键的顺序对元素进行排序
3.多级映射: 映射类可以嵌套使用,创建多级映射,这对于复杂的数据结构非常有用
4.键值对存储: 映射类专门设计用于存储键值对(key-value)
在这里插入图片描述

mapmultimap 之间的区别在于,后者能够存储重复的键,而前者只能存储唯一的键,要使用需要包含头文件<map>

1.实例化map和multimap

map实例化:

std::map<key_type, value_type> map_instance;
//key_type 是键的类型。
//value_type 是与每个键关联的值的类型。
#include <iostream>
#include <map>int main() {// 实例化std::map,键类型为int,值类型为std::stringstd::map<int, std::string> myMap;// 向map中添加元素myMap[1] = "one";myMap[2] = "two";myMap[3] = "three";// 打印map和multimap的内容std::cout << "Map:" << std::endl;for (const auto& pair : myMap) {std::cout << pair.first << " : " << pair.second << std::endl;}// 尝试添加重复的键,这将更新已存在的键对应的值myMap[1] = "ONE"; // "one" 将被 "ONE" 替换// 打印map的内容std::cout << "Map:" << std::endl;for (const auto& pair : myMap) {std::cout << pair.first << " : " << pair.second << std::endl;}system("pause");return 0;
}

multimap实例化:

std::multimap<key_type, value_type> multimap_instance;
//key_type 是键的类型,可以有重复。
//value_type 是与每个键关联的值的类型。
#include <iostream>
#include <map>int main() {// 实例化std::multimap,允许有相同键的多个元素std::multimap<int, std::string> myMultimap;// 向multimap中添加具有相同键的多个元素myMultimap.insert(std::make_pair(1, "uno"));myMultimap.insert(std::make_pair(1, "eins"));// 打印multimap的内容std::cout << "Multimap:" << std::endl;for (const auto& pair : myMultimap) {std::cout << pair.first << " : " << pair.second << std::endl;}system("pause");return 0;
}

2.在map和multimap中插入元素

使用insert()成员函数插入

//key为键,val为值
map.insert(std::make_pair(key,val));
map.insert(std::pair<int,string>(key,val));
map[key]=val;//multimap操作相同,但无法使用数组语法[]来插入
#include <iostream>
#include <map>
using namespace std;int main() {// 实例化std::multimap,允许有相同键的多个元素multimap<int, string> myMultimap;// 向multimap中添加具有相同键的多个元素myMultimap.insert(make_pair(1, "one"));myMultimap.insert(pair<int,string>(1, "two"));// 打印multimap的内容cout << "Multimap:" << endl;for (const auto& pair : myMultimap) {cout << pair.first << " : " << pair.second << endl;}//实例化std::mapmap<int,string> myMap;//向map中添加元素myMap[1]="map_one";myMap.insert(make_pair(2,"map_two"));myMap.insert(pair<int,string>(3,"map_three"));// 打印map的内容cout << "map:" << endl;for (const auto& pair : myMap) {cout << pair.first << " : " << pair.second << endl;}system("pause");return 0;
}

3.在map和multimap中查找元素

使用find()成员函数,该函数会返回一个迭代器

map中查找

#include <map>
#include <iostream>
#include <string>int main() {std::map<int, std::string> myMap;myMap[1] = "one";myMap[2] = "two";// 查找键为1的元素auto it = myMap.find(1);//检查是否查找成功if (it != myMap.end()) {//myMap.end()指向容器的末尾,即最后一个元素之后的位置//如果已经找到了,就不会指向这个位置,反之则没有找到std::cout << "Found: " << it->second << std::endl; // 输出 "Found: one"} else {std::cout << "Not found" << std::endl;}// 查找键为3的元素,这个键不存在于map中it = myMap.find(3);if (it == myMap.end()) {std::cout << "Not found" << std::endl;}system("pause");return 0;
}

multimap中查找
因为mulitimap允许包含多个键相同的键值对,所以可以用multimap::count()函数确定有多少个,再对迭代器进行递增,来访问这些值

#include <map>
#include <iostream>
#include <string>int main() {std::multimap<int, std::string> myMultimap;// 插入具有相同键的不同值的元素myMultimap.insert(std::make_pair(1, "one"));myMultimap.insert(std::make_pair(1, "ONE"));myMultimap.insert(std::make_pair(2, "two"));// 查找键为1的元素auto it = myMultimap.find(1);// 如果找到了至少一个元素if (it != myMultimap.end()) {// 使用count()确定键为1的元素数量size_t count = myMultimap.count(1);// 遍历所有具有键为1的元素for (size_t i = 0; i < count; ++i) {std::cout << it->second << " ";// 递增迭代器以移动到下一个具有相同键的元素++it;}}// 如果没有找到键为1的元素,输出"Not found"else {std::cout << "Not found" << std::endl;}system("pause");return 0;
}

4.删除map和multimap中的元素、

使用erase()函数,有以下几种版本

删除指定位置的元素

map.erase(iterator pos);//使用迭代器
map.erase(key);//使用键

删除指定范围的元素

map.erase(iterator first, iterator last);//使用迭代器确定边界
#include <map>
#include <iostream>
#include <string>int main() {std::multimap<int, std::string> myMultimap;// 插入具有相同键的不同值的元素myMultimap.insert(std::make_pair(1, "one"));myMultimap.insert(std::make_pair(1, "ONE"));myMultimap.insert(std::make_pair(2, "two"));myMultimap.insert(std::make_pair(3, "three"));myMultimap.insert(std::make_pair(4, "four"));myMultimap.insert(std::make_pair(5, "five"));//删除键为2myMultimap.erase(2);//删除键为1的元素myMultimap.erase(myMultimap.find(1));//只能删除one,而ONE删不掉//删除键3和键4auto it3=myMultimap.find(3);auto it4=myMultimap.find(4);myMultimap.erase(it3,it4);for(auto& pair:myMultimap){std::cout<<pair.first<<":"<<pair.second<<std::endl;}system("pause");return 0;
}

输出结果
请添加图片描述

5.提供自定义排序谓词

语法

#include <map>
#include <iostream>
#include <string>// 自定义比较函数
struct CustomCompare {bool operator()(int a, int b) const {// 基于字符串长度进行比较return std::to_string(a).length() < std::to_string(b).length();}
};int main() {// 使用自定义比较函数的std::mapstd::map<int, std::string, CustomCompare> myMap;// 使用自定义比较函数的std::multimapstd::multimap<int, std::string, CustomCompare> myMultimap;// 向map中插入元素。由于map中键必须是唯一的,这里插入的元素将根据自定义的比较逻辑被排序。myMap.insert({100, "Hundred"});myMap.insert({10, "Ten"});myMap.insert({1000, "Thousand"});// 向multimap中插入元素。multimap允许有相同键的多个元素。myMultimap.insert({100, "Hundred"});myMultimap.insert({10, "Ten"});myMultimap.insert({1000, "Thousand"});myMultimap.insert({100, "Another Hundred"}); // 允许重复键// 遍历map并打印键值对std::cout << "Map contents:" << std::endl;for (const auto& pair : myMap) {std::cout << pair.first << " : " << pair.second << std::endl;}// 遍历multimap并打印键值对std::cout << "Multimap contents:" << std::endl;for (const auto& pair : myMultimap) {std::cout << pair.first << " : " << pair.second << std::endl;}system("pause");return 0;
}

6.基于散列表的unordered_map和unordered_multimap

从C++11起,支持散列映射,要使用这两个容器,需要包含<unordered_map>,有以下特点

  1. 因为散列表的特性,理想情况下性能更高,最坏情况下性能更差
  2. 无序性

基本操作

#include <unordered_map>
#include <iostream>
#include <string>int main() {// 使用整数作为键,字符串作为值的unordered_mapstd::unordered_map<int, std::string> um;// 插入元素um.insert({1, "one"});um[2] = "two"; // 使用下标操作符// 查找元素auto it = um.find(1);if (it != um.end()) {std::cout << "Found: " << it->second << std::endl; // 输出 "Found: one"} else {std::cout << "Element with key 1 not found" << std::endl;}// 删除键为1的元素um.erase(1);// 再次尝试查找键为1的元素it = um.find(1);if (it == um.end()) {std::cout << "Element with key 1 not found after erase" << std::endl;}// 使用整数作为键,字符串作为值的unordered_multimapstd::unordered_multimap<int, std::string> umm;// 插入具有相同键的多个元素umm.insert({1, "one"});umm.insert({1, "ONE"});// 查找所有键为1的元素auto range = umm.equal_range(1);for (auto it = range.first; it != range.second; ++it) {std::cout << it->second << " "; // 输出 "one ONE"}std::cout << std::endl;// 删除所有键为1的元素umm.erase(1);// 再次查找键为1的元素,应该找不到range = umm.equal_range(1);if (std::distance(range.first, range.second) == 0) {std::cout << "No elements with key 1 found after erase" << std::endl;}system("pause");return 0;
}

相关文章:

《21天学通C++》(第二十章)STL映射类(map和multimap)

为什么需要map和multimap&#xff1a; 1.查找高效&#xff1a; 映射类允许通过键快速查找对应的值&#xff0c;这对于需要频繁查找特定元素的场景非常适合。 2.自动排序&#xff1a; 会自动根据键的顺序对元素进行排序 3.多级映射&#xff1a; 映射类可以嵌套使用&#xff0c;创…...

5月游戏市场迎来新的体验,网易两款游戏重磅出炉

易采游戏网5月9日消息&#xff0c;随着科技的飞速发展&#xff0c;手机游戏已经成为人们休闲娱乐的重要方式。在这个领域&#xff0c;网易作为国内领先的游戏开发商&#xff0c;一直致力于为玩家带来高品质的游戏体验。近日&#xff0c;网易携手国际大厂Square Enix&#xff0c…...

15_Scala面向对象编程_访问权限

文章目录 Scala访问权限1.同类中访问2.同包不同类访问3.不同包访问4.子类权限小结 Scala访问权限 知识点概念 private --同类访问private[包名] --包私有&#xff1b; 同类同包下访问protected --同类&#xff0c;或子类 //同包不能访问(default)(public)默认public --公…...

LeetCode|700. Search in Binary Search Tree

题目 You are given the root of a binary search tree (BST) and an integer val. Find the node in the BST that the node’s value equals val and return the subtree rooted with that node. If such a node does not exist, return null. Example 1: Input: root […...

MacOS下载安装JDK8

一、前言 今天给苹果电脑安装JDK环境&#xff0c;后续打算把Mac系统也用起来&#xff0c;也体验一把用苹果系统开发。 JDK就不过多介绍了&#xff0c;大家都是JAVA开发&#xff0c;JDK就是JAVA开发的必要环境。目前已经更新到JDK20了&#xff0c;不过我是不会更新的&#xff0…...

macOS 如何使用Visual Studio Code 编译C++

在 macOS,则默认系统 C++ 编译器是 Clang。 要使用 Visual Studio Code 在 macOS 上的 Clang 中指定 C++ 版本,可以按如下所示修改tasks.json 文件: 在 Visual Studio Code 中打开您的 C++ 项目。按 Ctrl+Shift+P(或 macOS 上的 Cmd+Shift+P)打开命令面板。在命令面板中键…...

SQLite3简单操作

SQLite命令 文章目录 SQLite命令一、创建数据库二、表的操作1、创建表2、删除表 一、创建数据库 注&#xff1a;使用Ubuntu服务器操作&#xff0c;安装sqlite3 sudo apt update sudo apt install sqlite3 sqlite3 --version1、SQLite主要使用命令sqlite3来创建新的数据库 sq…...

从“制造”到“智造”:“灯塔”经验助力中国制造业转型升级-转载

作者&#xff1a;Karel Eloot&#xff0c;侯文皓&#xff0c;Francisco Betti&#xff0c;Enno de Boer和Yves Giraud 作为中国实体经济的主体&#xff0c;制造业是推动中国经济发展乃至全球制造业持续增长的重要引擎。站在历史与未来交汇的新起点上&#xff0c;中国制造业将背…...

C++ 容器(二)——容器操作

一、容器的修改 容器修改函数 insert()&#xff1a;在指定位置插入一个或多个元素erase()&#xff1a;删除指定位置或指定范围的元素push_back()&#xff1a;将元素添加到容器的末尾pop_back()&#xff1a;删除容器的最后一个元素 push_front()&#xff1a;将元素添加到容器的开…...

操作系统——进程控制

创建进程 fork fork是一个系统调用函数&#xff0c;用来创建子进程&#xff0c;通过多个执行流完成任务。子进程和父进程共用一份代码&#xff0c;子进程数据使用写时拷贝&#xff0c;即子进程数据在创建的时候和父进程相同&#xff0c;但是当要修改数据的时候&#xff0c;子进…...

Marin说PCB之国产电源芯片方案 ---STC2620Q

随着小米加入的造车大家庭&#xff0c;让这个本来就卷的要死的造车大家庭更加卷了。随之带来的蝴蝶效应就是江湖上各个造成门派都开始了降本方案的浪潮啊&#xff0c;开始打响价格战了。各家的新能源车企也是不得不开始启动了降本方案的计划了&#xff0c;为了应对降价的浪潮。…...

已解决java.lang.StringIndexOutOfBoundsException: 字符串索引越界异常的正确解决方法,亲测有效!!!

已解决java.lang.StringIndexOutOfBoundsException: 字符串索引越界异常的正确解决方法&#xff0c;亲测有效&#xff01;&#xff01;&#xff01; 目录 问题分析 报错原因 解决思路 解决方法 检查索引范围 检查字符串长度 管理循环中的索引 总结 问题分析 java.lan…...

关于实体类注解@Data、@EqualsAndHashCode(callSuper = true)、@Accessors(chain = true)的作用

笔记&#xff1a;都是lombook插件的注解&#xff0c;作用是简化优化代码等&#xff0c;比如getter、setter&#xff0c;一般三者连用能避免一些如继承类的导致的一些坑&#xff0c;比如equal()方法的错误&#xff0c;具体用法可查阅每个注解及属性的作用。 Accessors(chain tr…...

5.9号模拟前端面试10问

5.9号模拟前端面试10问 1.html语义化的理解 HTML语义化是指使用具有明确含义的HTML标签来描述内容&#xff0c;而不仅仅是使用<div>和<span>等通用容器标签。语义化的HTML代码更易于阅读和维护&#xff0c;同时也有助于搜索引擎优化&#xff08;SEO&#xff09;。…...

vue3 JSX的使用与警告【JSX 元素隐式具有类型 “any“,因为不存在接口 “JSX.IntrinsicElements“】解决办法

一、安装 pnpm i vitejs/plugin-vue-jsx -D 二、配置 1、tsconfig.json "compilerOptions":{"jsx":"preserve" } 2、vite.config.ts import VueJsx from "vitejs/plugin-vue-jsx"...plugin:[vue(),VueJsx() ] 三、简单使用案例…...

一、计算机基础(Java零基础一)

&#x1f33b;&#x1f33b;目录 一、&#x1f33b;&#x1f33b;剖析学习Java前的疑问&#x1f33b;&#x1f33b;1.1 零基础学习编程1.2 英语不好能学吗&#xff1f;1.3 理解慢能学好吗&#xff1f;1.4 现在学Java晚吗&#xff1f;1.5 Java 和 Python 还有 Go 的选择1.6 Java…...

德国著名自动化公司Festo设计了一款仿生蜜蜂,仅重34g,支持多只蜜蜂编队飞行!...

德国著名的气动元件研发及自动化解决方案供应商Festo公司近日展示了一款仿生蜜蜂&#xff08;BionicBee&#xff09;&#xff0c;重量只有34g&#xff0c;却完全可以实现自主飞行&#xff0c;还支持多只相同的蜜蜂机器人编队飞行。 BionicBee 重约 34 克&#xff0c;长 22 厘米…...

折腾记:C++用开源库Snap7通过S7协议连接西门子PLC

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github&#xff1a;codetoys&#xff0c;所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的&#xff0c;可以在任何平台上使用。 不是教程&#xff0c;是避坑指…...

Android studio 新版本 NewUI toolbar显示快捷按钮

新版本的Android studio 启用新的界面&#xff0c;以前许多快捷按键位置有变化 文章目录 设置始终显示主菜单设置ToolBar快捷按钮显示设置右下角显示分支 设置始终显示主菜单 原本要点击左上角几个横向才显示的菜单 设置始终显示&#xff0c;View -> Appearance -> Mai…...

辛普森公式求函数的近似积分【通用计算】

利用辛普森公式可以近似求出复杂函数的积分值&#xff0c;公式如下&#xff1a; ∫ a b f ( x ) d x ≈ h 3 [ y 0 y 2 n − 1 4 ( ∑ i 1 n − 1 y 2 i − 1 ) ∑ i 1 n − 1 y 2 i ] \int_{a}^{b} f(x) dx \approx \frac{h}{3}\left[ y_0 y_{2n-1} 4(\sum\limits_{i1…...

k8s从入门到放弃之Ingress七层负载

k8s从入门到放弃之Ingress七层负载 在Kubernetes&#xff08;简称K8s&#xff09;中&#xff0c;Ingress是一个API对象&#xff0c;它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress&#xff0c;你可…...

【力扣数据库知识手册笔记】索引

索引 索引的优缺点 优点1. 通过创建唯一性索引&#xff0c;可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度&#xff08;创建索引的主要原因&#xff09;。3. 可以加速表和表之间的连接&#xff0c;实现数据的参考完整性。4. 可以在查询过程中&#xff0c;…...

什么是库存周转?如何用进销存系统提高库存周转率?

你可能听说过这样一句话&#xff1a; “利润不是赚出来的&#xff0c;是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业&#xff0c;很多企业看着销售不错&#xff0c;账上却没钱、利润也不见了&#xff0c;一翻库存才发现&#xff1a; 一堆卖不动的旧货…...

HBuilderX安装(uni-app和小程序开发)

下载HBuilderX 访问官方网站&#xff1a;https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本&#xff1a; Windows版&#xff08;推荐下载标准版&#xff09; Windows系统安装步骤 运行安装程序&#xff1a; 双击下载的.exe安装文件 如果出现安全提示&…...

AI编程--插件对比分析:CodeRider、GitHub Copilot及其他

AI编程插件对比分析&#xff1a;CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展&#xff0c;AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者&#xff0c;分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...

代理篇12|深入理解 Vite中的Proxy接口代理配置

在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...

华硕a豆14 Air香氛版,美学与科技的馨香融合

在快节奏的现代生活中&#xff0c;我们渴望一个能激发创想、愉悦感官的工作与生活伙伴&#xff0c;它不仅是冰冷的科技工具&#xff0c;更能触动我们内心深处的细腻情感。正是在这样的期许下&#xff0c;华硕a豆14 Air香氛版翩然而至&#xff0c;它以一种前所未有的方式&#x…...

NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合

在汽车智能化的汹涌浪潮中&#xff0c;车辆不再仅仅是传统的交通工具&#xff0c;而是逐步演变为高度智能的移动终端。这一转变的核心支撑&#xff0c;来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒&#xff08;T-Box&#xff09;方案&#xff1a;NXP S32K146 与…...

MySQL JOIN 表过多的优化思路

当 MySQL 查询涉及大量表 JOIN 时&#xff0c;性能会显著下降。以下是优化思路和简易实现方法&#xff1a; 一、核心优化思路 减少 JOIN 数量 数据冗余&#xff1a;添加必要的冗余字段&#xff08;如订单表直接存储用户名&#xff09;合并表&#xff1a;将频繁关联的小表合并成…...

MyBatis中关于缓存的理解

MyBatis缓存 MyBatis系统当中默认定义两级缓存&#xff1a;一级缓存、二级缓存 默认情况下&#xff0c;只有一级缓存开启&#xff08;sqlSession级别的缓存&#xff09;二级缓存需要手动开启配置&#xff0c;需要局域namespace级别的缓存 一级缓存&#xff08;本地缓存&#…...