【C++ STL有序关联容器】map 映射
文章目录
- 【 1. 基本原理 】
- 【 2. map 的创建 】
- 2.1 调用默认构造函数,创建一个空的 map
- 2.2 map 被构造的同时初始化
- 2.3 通过一个 queue 初始化另一个 queue
- 2.4 取已建 map 中指定区域内的键值对,初始化新的 map
- 2.5 指定排序规则
- 【 2. map 元素的操作 】
- 实例 - 查找键
- 实例 - map 某个键对应的值自加1
- 【 3 map 支持的成员方法 】
- 实例 - 输出map元素数量以及各个键值对
【 1. 基本原理 】
- map 容器存储的都是 pair 对象,用 pair 类模板创建的键值对,即
pair<const K, T>类型(其中 K 和 T 分别表示键和值的数据类型)的键值对元素。其中,各个键值对的键和值可以是任意数据类型,包括 C++ 基本数据类型(int、char、double 等)、使用结构体或类自定义的类型。通常情况下,map 容器中存储的各个键值对都选用 string 字符串作为键的类型。 - 与此同时,在使用 map 容器存储多个键值对时, map容器会自动根据各键值对中键的大小,按照既定的规则进行 自动排序。默认情况下,map 容器选用 std::less<T>排序规则(其中 T 表示键的数据类型),其会根据键的大小对所有键值 默认做升序排序。当然,根据实际情况的需要,我们可以手动指定 map 容器的排序规则,既可以选用 STL 标准库中提供的其它排序规则(比如std::greater<T>),也可以自定义排序规则。
- map 容器中存储的各个键值对 不仅键独一无二,键的类型也会用 const 修饰,这意味着使用 map 容器存储的各个键值对, 键 既不能重复也不能被修改。
【 2. map 的创建 】
- map 容器定义在 <map> 头文件 中,并位于 std 命名空间 中。
- map 容器的模板定义如下:
- map 容器模板有 4 个参数,其中后 2 个参数都设有默认值。大多数场景中,我们只需要设定前 2 个参数的值,有些场景可能会用到第 3 个参数,但最后一个参数几乎不会用到。
template < class Key, // 指定键(key)的类型class T, // 指定值(value)的类型class Compare = less<Key>, // 指定排序规则class Alloc = allocator<pair<const Key,T> > // 指定分配器对象的类型> class map;
2.1 调用默认构造函数,创建一个空的 map
- 通过此方式创建出的 myMap 容器,初始状态下是空的,即没有存储任何键值对。鉴于空 map 容器可以根据需要随时添加新的键值对,因此创建空 map 容器是比较常用的。
map<string, int>myMap;
2.2 map 被构造的同时初始化
- 在创建 map 容器的同时,也可以进行初始化,比如:
由此,myMap 容器在初始状态下,就包含有 2 个键值对。
map<string, int>myMap{ {"C语言教程",10},{"STL教程",20} };
- 再次强调,map 容器中存储的键值对,其本质都是 pair 类模板创建的 pair 对象。因此,下面程序也可以创建出一模一样的 myMap 容器:
map<string, int>myMap{make_pair("C语言程",10),make_pair("STL教程",20)};
2.3 通过一个 queue 初始化另一个 queue
- 在某些场景中,可以利用先前已创建好的 map 容器,再创建一个新的 map 容器。 无论是调用复制构造函数还是调用拷贝构造函数,前提是需要保证两个容器的类型一致。
- 通过调用 map 容器的 拷贝构造函数,即可成功创建一个和 myMap 完全一样的 newMap 容器。
map<string, int>newMap(myMap);
- C++ 11 标准中,还为 map 容器增添了 移动构造函数。当有临时的 map 对象作为参数,传递给要初始化的 map 容器时,此时就会调用移动构造函数。举个例子:
#创建一个会返回临时 map 对象的函数
map<string,int> disMap()
{map<string, int>tempMap{ {"C语言教程",10},{"STL教程",20} };return tempMap;
}
//调用 map 类模板的移动构造函数创建 newMap 容器
map<string, int>newMap(disMap());
2.4 取已建 map 中指定区域内的键值对,初始化新的 map
- map 类模板还支持取已建 map 容器中指定区域内的键值对,创建并初始化新的 map 容器。例如:
这里,通过调用 map 容器的双向迭代器,实现了在创建 newMap 容器的同时,将其初始化为包含一个 {“STL教程”,20} 键值对的容器。
map<string, int>myMap{ {"C语言教程",10},{"STL教程",20} };
map<string, int>newMap(++myMap.begin(), myMap.end());
2.5 指定排序规则
- 在以上几种创建 map 容器的基础上,我们都可以手动修改 map 容器的排序规则。
- 默认情况下,map 容器调用 std::less<T> 规则,根据容器内各键值对的键的大小,对所有键值对 默认做升序排序。
因此,如下 2 行创建 map 容器的方式,其实是等价的:
map<string, int>myMap{ {"C语言教程",10},{"STL教程",20} };
map<string, int, less<string> >myMap{ {"C语言教程",10},{"STL教程",20} };
以上 2 种创建方式生成的 myMap 容器,其内部键值对排列的顺序为:
<“C语言教程”, 10>
<“STL教程”, 20>
- 下面程序手动修改了 myMap 容器的排序规则,令其 指定做降序排序:
map<string, int, greater<string> >myMap{ {"C语言教程",10},{"STL教程",20} };
此时,myMap 容器内部键值对排列的顺序为:
<“STL教程”, 20>
<“C语言教程”, 10>
【 2. map 元素的操作 】
- 通过指定 键 的方式 访问键值对
如果 该键存在,则返回该键对应的值;否则返回0。
myMap[ 要查找的键 ]
- 通过迭代器的方式访问键值对
t->first为该迭代器对应的键,t->second为该迭代器对应的值。
auto t = myMap.begin();
cout << t->first << t->second << endl;//t->first为键,t->second为值
实例 - 查找键
#include <iostream>
#include <map>
#include <string>
using namespace std;
int main() {map<string,int>myMap;myMap.emplace("Nami", 98);myMap.emplace("Luffy", 99);myMap.emplace("Soro", 97);cout << myMap["Nami"] << endl;//存在键相应的键值对,返回对应的值cout << myMap["Sanj"] << endl; //没有键对应的键值对,返回0auto t = myMap.begin();cout << t->first << t->second << endl;//t->first为键,t->second为值return 0;
}

实例 - map 某个键对应的值自加1
#include <iostream>
#include <map>
#include <string>
using namespace std;
int main() {map<string,int>myMap;myMap.emplace("Nami", 1);myMap["Nami"]++;cout << myMap["Nami"] << endl;auto t = myMap.begin();t->second = t->second + 1;cout << t->second << endl;return 0;
}

【 3 map 支持的成员方法 】
| map支持的成员方法 | 功能 |
|---|---|
| begin() | 返回指向容器中第一个(注意,是已排好序的第一个)键值对的双向迭代器。如果 map 容器用 const 限定,则该方法返回的是 const 类型的双向迭代器。 |
| end() | 返回指向容器最后一个元素(注意,是已排好序的最后一个)所在位置后一个位置的双向迭代器,通常和 begin() 结合使用。如果 map 容器用 const 限定,则该方法返回的是 const 类型的双向迭代器。 |
| rbegin() | 返回指向最后一个(注意,是已排好序的最后一个)元素的反向双向迭代器。如果 map 容器用 const 限定,则该方法返回的是 const 类型的反向双向迭代器。 |
| rend() | 返回指向第一个(注意,是已排好序的第一个)元素所在位置前一个位置的反向双向迭代器。如果 map 容器用 const 限定,则该方法返回的是 const 类型的反向双向迭代器。 |
| cbegin() | 和 begin() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改容器内存储的键值对。 |
| cend() | 和 end() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改容器内存储的键值对。 |
| crbegin() | 和 rbegin() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改容器内存储的键值对。 |
| crend() | 和 rend() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改容器内存储的键值对。 |
| find(key) | 在 map 容器中查找键为 key 的键值对,如果成功找到,则返回指向该键值对的双向迭代器;反之,则返回和 end() 方法一样的迭代器。另外,如果 map 容器用 const 限定,则该方法返回的是 const 类型的双向迭代器。 |
| lower_bound(key) | 返回一个指向当前 map 容器中第一个大于或等于 key 的键值对的双向迭代器。如果 map 容器用 const 限定,则该方法返回的是 const 类型的双向迭代器。 |
| upper_bound(key) | 返回一个指向当前 map 容器中第一个大于 key 的键值对的迭代器。如果 map 容器用 const 限定,则该方法返回的是 const 类型的双向迭代器。 |
| equal_range(key) | 该方法返回一个 pair 对象(包含 2 个双向迭代器),其中 pair.first 和 lower_bound() 方法的返回值等价,pair.second 和 upper_bound() 方法的返回值等价。也就是说,该方法将返回一个范围,该范围中包含的键为 key 的键值对(map 容器键值对唯一,因此该范围最多包含一个键值对)。 |
| empty() | 若容器为空,则返回 true;否则 false。 |
| size() | 返回当前 map 容器中存有键值对的个数。 |
| max_size() | 返回 map 容器所能容纳键值对的最大个数,不同的操作系统,其返回值亦不相同。 |
| operator[] | map容器重载了 [] 运算符,只要知道 map 容器中某个键值对的键的值,就可以向获取数组中元素那样,通过键直接获取对应的值。 |
| at(key) | 找到 map 容器中 key 键对应的值,如果找不到,该函数会引发 out_of_range 异常。 |
| insert() | 向 map 容器中插入键值对。 |
| erase() | 删除 map 容器指定位置、指定键(key)值或者指定区域内的键值对。后续章节还会对该方法做重点讲解。 |
| swap() | 交换 2 个 map 容器中存储的键值对,这意味着,操作的 2 个键值对的类型必须相同。 |
| clear() | 清空 map 容器中所有的键值对,即使 map 容器的 size() 为 0。 |
| emplace() | 在当前 map 容器中的指定位置处构造新键值对。其效果和插入键值对一样,但效率更高。 |
| emplace_hint() | 在本质上和 emplace() 在 map 容器中构造新键值对的方式是一样的,不同之处在于,使用者必须为该方法提供一个指示键值对生成位置的迭代器,并作为该方法的第一个参数。 |
| count(key) | 在当前 map 容器中,查找键为 key 的键值对的个数并返回。注意,由于 map 容器中各键值对的键的值是唯一的,因此该函数的返回值最大为 1。 |
实例 - 输出map元素数量以及各个键值对
- 创建 1个 map,输出map元素数量,最后输出各个键值对。
#include <iostream>
#include <map>
#include <string>
using namespace std;
int main() {//创建空 map 容器,默认根据个键值对中键的值,对键值对做降序排序map<string, string,greater<string>>myMap;//调用 emplace() 方法,直接向 myMap 容器中指定位置构造新键值对myMap.emplace("C语言教程", "http://c.biancheng.net/c/");myMap.emplace("Python教程", "http://c.biancheng.net/python/");myMap.emplace("STL教程", "http://c.biancheng.net/stl/");//输出当前 myMap 容器存储键值对的个数cout << "myMap size==" << myMap.size() << endl;//输出键值对if (!myMap.empty()) //判断当前 myMap 容器是否为空{//借助 myMap 容器迭代器,将该容器的键值对逐个输出for (auto i = myMap.begin(); i != myMap.end(); ++i)cout << i->first << " " << i->second << endl;}return 0;
}

- 统计字符串中各字母字符对应的个数
#include <iostream>
#include<map>
using namespace std;
int main() {char str[100] = { 0 };cin.getline(str, sizeof(str));map<char, int>maps;for (int i = 0; str[i] != '\0'; i++) {if (isalpha(str[i]))//判断是否是字符maps[str[i]]++;//maps[str[i]]++指的是取出map对应key的value值再累加,如果没有对应的键则会自动加入map中 }for (auto it = maps.begin(); it != maps.end(); it++){cout << it->first << ":" << it->second << endl;}return 0;
}

相关文章:
【C++ STL有序关联容器】map 映射
文章目录 【 1. 基本原理 】【 2. map 的创建 】2.1 调用默认构造函数,创建一个空的 map2.2 map 被构造的同时初始化2.3 通过一个 queue 初始化另一个 queue2.4 取已建 map 中指定区域内的键值对,初始化新的 map2.5 指定排序规则 【 2. map 元素的操作 】…...
【ZZULIOJ】1041: 数列求和2(Java)
目录 题目描述 输入 输出 样例输入 Copy 样例输出 Copy code 题目描述 输入一个整数n,输出数列1-1/31/5-……前n项的和。 输入 输入只有一个整数n。 输出 结果保留2为小数,单独占一行。 样例输入 Copy 3 样例输出 Copy 0.87 code import java.util…...
C++【适配器模式】
简单介绍 适配器模式是一种结构型设计模式 | 它能使接口不兼容的对象能够相互合作。(是适配各种不同接口的一个中间件) 基础理解 举个例子:当你引用了一个第三方数据分析库,但这个库的接口只能兼容JSON 格式的数据。但你需要它…...
go | 上传文件分析 | http协议分析 | 使用openssl 实现 https 协议 server.key、server.pem
是这样的,现在分析抓包数据 test.go package mainimport ("fmt""log""github.com/gin-gonic/gin" )func main() {r : gin.Default()// Upload single filer.MaxMultipartMemory 8 << 20r.POST("/upload", func(c *g…...
Chatgpt掘金之旅—有爱AI商业实战篇|专业博客|(六)
演示站点: https://ai.uaai.cn 对话模块 官方论坛: www.jingyuai.com 京娱AI 一、AI技术创业博客领域有哪些机会? 人工智能(AI)技术作为当今科技创新的前沿领域,为创业者提供了广阔的机会和挑战。随着AI技…...
单例模式 JAVA
单例模式 什么是单例模式? 1、单例类只能有一个实例。2、单例类必须自己创建自己的唯一实例。3、单例类必须给所有其他对象提供这一实例。 应用:数据库的连接类,这样就可以确保只创建一次。节省资源。 单例模式代码:涉及懒加载…...
C++从入门到精通——初步认识面向对象及类的引入
初步认识面向对象及类的引入 前言一、面向过程和面向对象初步认识C语言C 二、类的引入C的类名代表什么示例 C与C语言的struct的比较成员函数访问权限继承默认构造函数默认成员初始化结构体大小 总结 前言 面向过程注重任务的流程和控制,适合简单任务和流程固定的场…...
GitHub入门与实践
ISBN: 978-7-115-39409-5 作者:【日】大塚弘记 译者:支鹏浩、刘斌 页数:255页 阅读时间:2023-08-05 推荐指数:★★★★★ 好久之前读完的了,一直没有写笔记。 这本入门Git的书籍还是非常推荐的,…...
centos 安装 stable-diffusion 详细流程
一、安装git 新版 先安装git 工具来更新git源码 , 载下源码后卸载git 版本(centos 默认1.8版本,说是安装会引起失败) 安装git 命令,可使用 git --version查看版本 sudo yum install git -y 卸载git命令 sudo yum remove git 正式源码安装…...
CSS编写登录框样式
/* 重置浏览器默认样式 */ * { margin: 0; padding: 0; box-sizing: border-box; } /* 设置登录框的基本样式 */ .login-box { width: 100%; max-width: 400px; margin: 50px auto; background-color: #f4f4f4; padding: 20px; box-shad…...
Python|OpenCV-获取鼠标点击位置的坐标,并绘制图像(13)
前言 本文是该专栏的第14篇,后面将持续分享OpenCV计算机视觉的干货知识,记得关注。 本文主要来详细说明,基于OpenCV来获取鼠标点击位置的坐标,并按坐标的位置进行自动绘制图像。具体怎么实现,笔者在正文中将结合实际代码案例进行详细说明。 具体细节部分以及完整代码的实…...
设计模式(14):命令模式
介绍 将一个请求封装为一个对象,从而使我们可用不同的请求对象客户进行参数化;对请求排队或者记录请求日志,以及支持可撤销的操作。也称之为:动作Action模式,事务transaction模式。 命令模式角色 抽象命令类(Comman…...
关于阿里云云数据库自动扩缩容和自动SQL优化的20道面试题
1. 请解释阿里云云数据库自动扩缩容的概念及其工作原理。 阿里云云数据库自动扩缩容是一种基于数据库实例的实时性能数据,能够发现流量异常并提供合理的数据库规格建议和磁盘容量建议的功能。其工作原理如下: 性能监控:系统会实时监控数据库…...
mkcert生成ssl证书+nginx部署局域网内的https服务访问问题
文章目录 mkcert生成ssl证书nginx部署局域网内的https服务访问问题1、下载mkcert查看自己的电脑是arm还是amd架构 2、安装mkcert3、测试mkcert是否安装成功4、查看CA证书存放位置5、打开windows的证书控制台6、生成自签证书,可供局域网内使用其他主机访问以下是nginx部署https服…...
PTA C 1050 螺旋矩阵(思路与优化)
本题要求将给定的 N 个正整数按非递增的顺序,填入“螺旋矩阵”。所谓“螺旋矩阵”,是指从左上角第 1 个格子开始,按顺时针螺旋方向填充。要求矩阵的规模为 m 行 n 列,满足条件:mn 等于 N;m≥n;且…...
神经网络分类和回归任务实战
学习方法:torch 边用边学,边查边学 真正用查的过程才是学习的过程 直接上案例,先来跑,遇到什么解决什么 数据集Minist 数据集 做简单的任务 Minist 分类任务 总体代码(可以跑通) from pathlib import …...
【数据结构】考研真题攻克与重点知识点剖析 - 第 4 篇:串
前言 本文基础知识部分来自于b站:分享笔记的好人儿的思维导图与王道考研课程,感谢大佬的开源精神,习题来自老师划的重点以及考研真题。此前我尝试了完全使用Python或是结合大语言模型对考研真题进行数据清洗与可视化分析,本人技术…...
深入浅出 -- 系统架构之分布式多形态的存储型集群
一、多形态的存储型集群 在上阶段,我们简单聊了下集群的基本知识,以及快速过了一下逻辑处理型集群的内容,下面重点来看看存储型集群,毕竟这块才是重头戏,集群的形态在其中有着多种多样的变化。 逻辑处理型的应用&…...
STL —— list
博主首页: 有趣的中国人 专栏首页: C专栏 本篇文章主要讲解 list模拟实现的相关内容 1. list简介 列表(list)是C标准模板库(STL)中的一个容器,它是一个双向链表数据结构,…...
申请SSL证书
有很多方法可以确保您的网站安全。添加SSL证书可针对恶意攻击提供额外且关键的保护层。 即使网站不接受交易,您仍然需要保护用户的登录详细信息、地址和其他个人信息。 没有SSL证书的网站使用HTTP(一种基于文本的协议),这意味着…...
Prompt Tuning、P-Tuning、Prefix Tuning的区别
一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...
深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法
深入浅出:JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中,随机数的生成看似简单,却隐藏着许多玄机。无论是生成密码、加密密钥,还是创建安全令牌,随机数的质量直接关系到系统的安全性。Jav…...
[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?
论文网址:pdf 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正!文章偏向于笔记,谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...
3-11单元格区域边界定位(End属性)学习笔记
返回一个Range 对象,只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意:它移动的位置必须是相连的有内容的单元格…...
Kafka入门-生产者
生产者 生产者发送流程: 延迟时间为0ms时,也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于:异步发送不需要等待结果,同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...
MySQL 索引底层结构揭秘:B-Tree 与 B+Tree 的区别与应用
文章目录 一、背景知识:什么是 B-Tree 和 BTree? B-Tree(平衡多路查找树) BTree(B-Tree 的变种) 二、结构对比:一张图看懂 三、为什么 MySQL InnoDB 选择 BTree? 1. 范围查询更快 2…...
HubSpot推出与ChatGPT的深度集成引发兴奋与担忧
上周三,HubSpot宣布已构建与ChatGPT的深度集成,这一消息在HubSpot用户和营销技术观察者中引发了极大的兴奋,但同时也存在一些关于数据安全的担忧。 许多网络声音声称,这对SaaS应用程序和人工智能而言是一场范式转变。 但向任何技…...
基于鸿蒙(HarmonyOS5)的打车小程序
1. 开发环境准备 安装DevEco Studio (鸿蒙官方IDE)配置HarmonyOS SDK申请开发者账号和必要的API密钥 2. 项目结构设计 ├── entry │ ├── src │ │ ├── main │ │ │ ├── ets │ │ │ │ ├── pages │ │ │ │ │ ├── H…...
二维FDTD算法仿真
二维FDTD算法仿真,并带完全匹配层,输入波形为高斯波、平面波 FDTD_二维/FDTD.zip , 6075 FDTD_二维/FDTD_31.m , 1029 FDTD_二维/FDTD_32.m , 2806 FDTD_二维/FDTD_33.m , 3782 FDTD_二维/FDTD_34.m , 4182 FDTD_二维/FDTD_35.m , 4793...
