【C++ STL有序关联容器】map 映射

文章目录

  • 【 1. 基本原理 】
  • 【 2. map 的创建 】
    • 2.1 调用默认构造函数,创建一个空的 map
    • 2.2 map 被构造的同时初始化
    • 2.3 通过一个 map 初始化另一个 map
    • 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 通过一个 map 初始化另一个 map

  • 在某些场景中,可以利用先前已创建好的 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;
}

在这里插入图片描述

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

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

相关文章

Bioorganic Chemistry:中国药科大学王鹏课题组、陈俊青课题组设计的基于AIE机理的高荧光选择性鉴定Cys/HCy

文献来源&#xff1a;Highly selective fluorescent probe based on AIE for identifying cysteine/homocysteine - PubMed (nih.gov) 一、AIE机理在荧光探针设计方向的应用&#xff1a; 参考文献&#xff1a;几种代表性的AIE的发光特点和机制&#xff08;2020-10-11&#xff…

PostgreSQL入门到实战-第六弹

PostgreSQL入门到实战 PostgreSQL查询语句(三)官网地址PostgreSQL概述PostgreSQL中ORDER BY理论PostgreSQL中ORDER BY实操更新计划 PostgreSQL查询语句(三) 官网地址 声明: 由于操作系统, 版本更新等原因, 文章所列内容不一定100%复现, 还要以官方信息为准 https://www.post…

蓝桥杯刷题--RDay5

清理水域--枚举 8.清理水域 - 蓝桥云课 (lanqiao.cn)https://www.lanqiao.cn/problems/2413/learning/?page1&first_category_id1&second_category_id3&tags2023 小蓝有一个n m大小的矩形水域&#xff0c;小蓝将这个水域划分为n行m列&#xff0c;行数从1…

Docker入门指南:从安装到基本操作和镜像构建的全面教程

文章目录 一、Docker简介二、Docker的安装三、Docker的基本概念四、Docker的基本操作五、Dockerfile和镜像构建六、总结 一、Docker简介 Docker是一个开源的应用容器引擎&#xff0c;它允许开发者将应用程序及其依赖项打包到一个可移植的容器中&#xff0c;然后在任何支持Dock…

人民网至顶科技:《开启智能新时代:2024中国AI大模型产业发展报告发布》

​3月26日&#xff0c;人民网财经研究院与至顶科技联合发布《开启智能新时代&#xff1a;2024年中国AI大模型产业发展报告》。该报告针对AI大模型产业发展背景、产业发展现状、典型案例、挑战及未来趋势等方面进行了系统全面的梳理&#xff0c;为政府部门、行业从业者以及社会公…

如何避免儿童校园霸凌:羊大师为您支招

校园应是学习和成长的乐土&#xff0c;而非恐惧和伤害的源泉。**在这个追求和谐社会的时代&#xff0c;校园霸凌问题依然是一个亟需解决的社会现象。羊大师作为关心儿童成长的一员&#xff0c;今天将为家长和教育工作者提供一些实用建议&#xff0c;帮助孩子避免成为校园霸凌的…

Python Selenium UI自动化测试

&#x1f525; 交流讨论&#xff1a;欢迎加入我们一起学习&#xff01; &#x1f525; 资源分享&#xff1a;耗时200小时精选的「软件测试」资料包 &#x1f525; 教程推荐&#xff1a;火遍全网的《软件测试》教程 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1…

IO-DAY8

使用消息队列去实现2个终端之间的互相聊天 要求:千万不要做出来2个终端之间的消息发送是读一写的&#xff0c;一定要能够做到&#xff0c;一个终端发送n条消息&#xff0c;另一个终端一条消息都不回复 A终端&#xff1a; #include<myhead.h> typedef struct msgbuf {lon…

设计模式学习笔记 - 设计模式与范式 -行为型:8.状态模式:游戏、工作流引擎中常用的状态机是如何实现的?

概述 本章学习状态模式。在实际的开发中&#xff0c;状态模式并不是很常用&#xff0c;但是在能够用到的场景里&#xff0c;它可以发挥很大的作用。从这一点上看&#xff0c;它有点像我们之前讲到的组合模式。 状态模式一般用来实现状态机&#xff0c;而状态机常用在游戏、工…

【C++】用红黑树封装map和set

我们之前学的map和set在stl源码中都是用红黑树封装实现的&#xff0c;当然&#xff0c;我们也可以模拟来实现一下。在实现之前&#xff0c;我们也可以看一下stl源码是如何实现的。我们上篇博客写的红黑树里面只是一个pair对象&#xff0c;这对于set来说显然是不合适的&#xff…

基于JAVA的汽车售票网站论文

摘 要 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播&#xff0c;搭配信息管理工具可以很好地为人们提供服务。针对汽车售票信息管理混乱&#xff0c;出错率高&#xff0c;信息安全性差…

AI技术将影响更长远,比如未来的就业形势

随着人工智能渗透到工作场所&#xff0c;人类将需要掌握新的工作技能。 AI作为新技术已经开始扰乱就业市场了。对于最新的AI人工智能技术&#xff0c;经济学家、教育工作者、监管机构、商业分析师以及相关领域专家预测&#xff0c;在不久的将来&#xff0c;人工智能一代将需要…

AI智能调色解决方案,节省了企业的时间和人力成本

如何确保图片、视频的色彩准确、生动&#xff0c;成为企业提升品牌形象和传播效果的重要课题。美摄科技凭借领先的AI技术&#xff0c;推出全新的AI智能调色解决方案&#xff0c;以智能化、精细化的调色方式&#xff0c;帮助企业轻松驾驭色彩&#xff0c;展现视觉魅力。 美摄科…

CSDN 广告太多,停更通知,转移到博客园

文章目录 前言新博客地址 前言 CSDN的广告实在是太多了&#xff0c;我是真的有点忍不了。直接把广告插在我的文章中间。而且我已经懒得找工作了&#xff0c;我当初写CSDN的目的就是为了找工作&#xff0c;有个博客排名。当时经济环境实在是太差了。我也没必要纠结这个2000粉丝…

Facebook直播延迟过高是为什么?

在进行Facebook直播 时&#xff0c;高延迟可能会成为一个显著的问题&#xff0c;影响观众的观看体验和互动效果。以下是一些导致Facebook直播延迟过高的可能原因&#xff1a; 1、网络连接问题 网络连接不稳定或带宽不足可能是导致Facebook直播延迟的主要原因之一。如果您的网络…

EDM邮件群发推广多少钱?有哪些优势?

电子邮件营销&#xff08;Electronic Direct Mail, EDM&#xff09;以其高性价比、精准定向与可度量效果的优势&#xff0c;成为众多企业不可或缺的营销策略。云衔科技&#xff0c;作为企业数字广告营销和SaaS软件服务的领军者&#xff0c;以其创新的智能EDM邮件营销系统解决方…

数学基础:常见函数图像

来自&#xff1a; https://www.desmos.com/calculator/l3u8133jwj?langzh-CN 推荐: https://www.shuxuele.com/index.html 一、三角函数 1.1 正弦 sin(x) 1.2 余弦 cos(x) 1.3 正切 tan(x) 1.4 余切 cot(x) 1.5 正弦余弦综合 1.6 正切余切综合 二、指数对数

【THM】Metasploit: Exploitation(利用)-初级渗透测试

介绍 在这个房间里,我们将学习如何使用Metasploit进行漏洞扫描和利用。我们还将介绍数据库功能如何使管理更广泛范围的渗透测试活动变得更容易。最后,我们将研究使用msfvenom生成有效负载以及如何在大多数目标平台上启动Meterpreter会话。 更具体地说,我们将讨论的主题是:…

前端:自制年历

详细思路可以看我的另一篇文章《前端&#xff1a;自制月历》&#xff0c;基本思路一致&#xff0c;只是元素布局略有差异 ①获取起始位startnew Date(moment().format(yyyy-01-01)).getDay() ②获取总的格子数numMath.ceil(365/7)*7,这里用365或者366计算结果都是一样的371 …

蓝桥杯刷题-16-买瓜-DFS+剪枝优化⭐⭐

蓝桥杯2023年第十四届省赛真题-买瓜 该如何剪枝呢&#xff1f;⭐⭐ 如果当前方案的切的刀数&#xff0c;已经大于等于了之前已知合法方案的最优解&#xff0c;那么就没必要 往后搜了。如果后面的瓜的总和加起来&#xff0c;再加上当前已有的重量&#xff0c;都不到m,那么也没…