C++相关概念和易错语法(24)(map、迭代器分类)

1.map

在上篇文章中,我着重介绍了set,由于map和set同源,所以这次我会着重介绍map别于set的地方

(1)模板参数

set是以单一的key作为成员变量,而map是以pair作为成员变量,而pair的first作为key来决定插入位置,second与first一一对应。唯一需要注意的就是map插入pair后不能修改key只能修改value。逻辑上也是必须的,因为map底层的平衡树就是依靠key的大小来建立的,改了key之后这个结点的位置就不对了,整棵树都被毁了。(关联式容器)

(2)构造函数

构造函数和set一样简洁,注意传参仿函数对象和实例化类型要匹配,写不写无所谓,编译器其会自动生成

(3)insert

map的insert和set的一模一样,都是插入数据,返回pair

但是要注意map的insert对象是pair,下面有几种方式:

make_pair

make_pair是一个模板函数,有两个模板参数,可以通过传入参数的类型来推理并实例化,返回对应的匿名pair对象。值得注意的是,pair类型之间能够发生类型转换

这里可以看到,当make_pair的返回值类型和实例化类型不同时,可以发生隐式类型转换,转换的规则遵循first和second分别的转换规则

同样的,当插入pair的类型和map对应的pair类型不相同时,也能发生隐式类型转换。这也进一步验证了pair的本质只是一个存储数据的类型,其实这也依赖pair的operator=函数的支持。

除了make_pair构造以外,还有两种构造,都很好理解

(4)initializer_list

在C++11之后,所有的容器都支持了initializer_list

我们需要抓住当用初始化列表时,最外层{}是初始化列表的标志,({1, 2, 3})标志参数为初始化列表,初始化列表里又可以使用{}标志隐式类型转换,当初始化时可以省略=(如m3)

这里要慢慢消化,可以结合C++相关概念和易错语法(14)(初始化注意事项、vector、编译器向上查找规则)多练习

(5)map里没有流插入,pair也没有流插入,需要自己显式写

(6)find、lower_bound、upper_bound用法和set一模一样,返回值均为迭代器

count、erase返回值均为size_t,标志找到的元素个数

(7)map中iterator的使用

我们要抓住迭代器的本质是模拟指向存储元素的指针,存储的是pair,一个自定义类型,所以operator->就派上了大用场,这也是我们遇到的第一个operator->特殊处理后有实用的地方。

在set中由于是key单独作为存储数据,就没有operator->的概念,直接*it就得到数据了

我们要着重区分pair<iterator, bool>和iterator因为iterator指向的元素也是pair,在调用的时候分不清什么时候用.什么时候用->

(8)operator[]

这可以说是map中的一大难点,在vector、deque中的operator[]可以和*it互换,换句话说,我们之前接触的容器的operator[]本质上和数组的[]没什么区别,是随机迭代器的标配。

但map中是双向迭代器(功能少于随即迭代器)本应没有operator[],但STL让它支持operator[],这也使得它拥有了非同寻常的实现过程和功能。

下面是详细的分析

其中需要注意的是value的默认构造包括自定义类型和内置类型的默认构造,内置类型的默认构造如int(),它的返回值为0(所有编译器都是这样处理的)

理解了上面这些,我们就能利用map实现更多功能了

这已经不是传统opeartor[]的用法了,由于强制支持operator[],map可以向上面那样以很直观的方式插入修改和查找。

(9)范围for

迭代器模拟的是容器元素的指针,范围for返回的是元素的拷贝或引用

两者的底层都是迭代器,但是表层一个是模拟指针,一个是值或值的引用

在map中使用范围for建议都使用const auto&,因为如果返回值给e,那么每次都要构造一个pair,pair中还可能有自定义类型,这样开销太大了,直接用const引用效率会高很多

(10)multimap

multimap和map的区别类似于multiset和set的区别,都是支持多个key的存储,没有去重功能。但multimap没有operator[],因为同一个key可能对应不同value,没有意义。当使用迭代器遍历时同样遵循其元素pair的比较逻辑。

2.迭代器分类 

我们已经接触过了string、vector、list、deque、stack、queue、priority_queue、map、set、multiset、multimap这些基本容器,我们会发现这些容器中有的没有迭代器,有的迭代器支持随意+num,如string,有的就不行,如list。出现这样的原因是迭代器也有它的分类,不同的迭代器有不同的功能,有的算法库的函数只能用特定迭代器才能使用。

随机迭代器:string、vector、deque

双向迭代器:list、map、set、multiset、multimap

无迭代器:stack、queue、priority_queue

不同的迭代器有不同的功能,下面是随机迭代器和双向迭代器的比较

由于两种迭代器的功能差异较大,一种是逐个访问,一种可以跳跃访问,在一些对访问灵活度要求高的算法中,就不能传双向迭代器而只能传随机迭代器,如sort

所以在很多时候我们需要转换容器。看看下面的代码,尝试加深理解


#include <iostream>
#include <algorithm>
#include <map>
#include <vector>using namespace std;struct Compare
{bool operator()(const pair<string, string>& p1, const pair<string, string>& p2) const{return p1 < p2;}
};int main()
{map<string, string> m;m["Huawei"] = "华为";m["Xiaomi"] = "小米";m["Apple"] = "苹果";m["Samsung"] = "三星";vector<pair<string, string>> v(m.begin(), m.end());sort(v.begin(), v.end(), Compare());for (const auto& e : v){cout << e.first << " " << e.second << endl;}return 0;
}

结果是

但是这里有个疑问,为什么可以用map的迭代器来初始化vector?有没有要求呢?这就需要引出另外几个迭代器:输入迭代器

此外还有剩余两个迭代器:输出迭代器、前向迭代器

我们重点区分双向迭代器和随机迭代器,很多容器都是这两种迭代器之一。在特定情况下我们也知道去切换容器。

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

mysql对数据库的增删改

目录 DML语句&#xff1a; 增加数据&#xff08;insert语句&#xff09; 增加数据&#xff08;insert into select&#xff09; 修改数据&#xff08;update语句&#xff09; 【where 子句条件】 删除数据&#xff08;delete语句&#xff09; 删除数据&#xff08;trunca…

【北京迅为】《i.MX8MM嵌入式Linux开发指南》-第三篇 嵌入式Linux驱动开发篇-第四十一章 物理地址与虚拟地址

i.MX8MM处理器采用了先进的14LPCFinFET工艺&#xff0c;提供更快的速度和更高的电源效率;四核Cortex-A53&#xff0c;单核Cortex-M4&#xff0c;多达五个内核 &#xff0c;主频高达1.8GHz&#xff0c;2G DDR4内存、8G EMMC存储。千兆工业级以太网、MIPI-DSI、USB HOST、WIFI/BT…

C# 委托函数 delegate

在C#中&#xff0c;委托&#xff08;Delegate&#xff09;是一种特殊的类型&#xff0c;它可以持有对方法的引用。 委托是实现事件的基础。事件本质上是多播委托&#xff0c;允许多个方法被触发 委托允许你将方法作为参数传递给其他方法&#xff0c;或者将方法作为返回值从方法…

基于生物地理算法的MLP多层感知机优化matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 4.1 生物地理算法&#xff08;BBO&#xff09;原理 4.2 多层感知机&#xff08;MLP&#xff09; 4.3 BBO优化MLP参数 5.完整程序 1.程序功能描述 基于生物地理算法的MLP多层感知机优化mat…

昇思25天学习打卡营第23天|ShuffleNet图像分类

ShuffleNet网络介绍 ShuffleNetV1是旷视科技提出的一种计算高效的CNN模型&#xff0c;和MobileNet, SqueezeNet等一样主要应用在移动端&#xff0c;所以模型的设计目标就是利用有限的计算资源来达到最好的模型精度。ShuffleNetV1的设计核心是引入了两种操作&#xff1a;Pointw…

Validated 中常用的注解

Validated 中常用的注解 导入依赖常用注解嵌套校验校验注解的三个参数在post 和 [get](https://so.csdn.net/so/search?qget&spm1001.2101.3001.7020) 请求上使用 添加全局异常处理器&#xff0c;处理参数验证异常 导入依赖 <dependency><groupId>org.spring…

蒙特卡罗模型★★★★★

该博客为个人学习清风建模的学习笔记&#xff0c;部分课程可以在B站&#xff1a;【强烈推荐】清风&#xff1a;数学建模算法、编程和写作培训的视频课程以及Matlab等软件教学_哔哩哔哩_bilibili 目录 1引例&#xff1a;布丰投针实验 2蒙特卡罗方法概述 2.1定义 2.2提出 2…

基于词级ngram的词袋模型对twitter数据进行情感分析

按照阿光的项目做出了学习笔记&#xff0c;pytorch深度学习实战项目100例 基于词级ngram的词袋模型对twitter数据进行情感分析 什么是 N 符&#xff1f; N 格是指给定文本或语音样本中 n 个项目的连续序列。这些项目可以是音素、音节、字母、单词或碱基对&#xff0c;具体取…

C++ 基础和基本语法

文章目录 1. 简介 2. 基本解释 示例解释 3. 程序结构 HELLO WORLD 编译 & 执行 C 程序 4. 分号 和 语句块 5. 标识符 6. 关键字 7. 注释 1. 简介 C 是一种静态类型的、编译式的、通用的、大小写敏感的、不规则的编程语言&#xff0c;支持过程化编程、面向对象编…

JAVA毕业设计634—基于Java+SSM的校园快递物流管理系统(源代码+数据库+11000字论文)

毕设所有选题&#xff1a; https://blog.csdn.net/2303_76227485/article/details/131104075 基于JavaSSM的校园快递物流管理系统(源代码数据库11000字论文)634 一、系统介绍 本项目分为用户、快递员、管理员三种角色 1、用户&#xff1a; 注册、登录、待取件信息管理、快…

【视觉SLAM】 十四讲ch5习题

1.*寻找一个相机&#xff08;你手机或笔记本的摄像头即可&#xff09;&#xff0c;标定它的内参。你可能会用到标定板&#xff0c;或者自己打印一张标定用的棋盘格。 参考我之前写过的这篇博客&#xff1a;【OpenCV】 相机标定 calibrateCamera Code来源是《学习OpenCV3》18.…

全国区块链职业技能大赛国赛考题前端功能开发

任务3-1:区块链应用前端功能开发 1.请基于前端系统的开发模板,在登录组件login.js、组件管理文件components.js中添加对应的逻辑代码,实现对前端的角色选择功能,并测试功能完整性,示例页面如下: 具体要求如下: (1)有明确的提示,提示用户选择角色; (2)用户可看…

2024年第二季度 DDoS 威胁趋势报告

2024 年上半年&#xff0c;Cloudflare 缓解了 850 万次 DDoS 攻击&#xff1a;第一季度 450 万次&#xff0c;第二季度 400 万次。总体而言&#xff0c;第二季度 DDoS 攻击数量环比下降了 11%&#xff0c;但同比增长了 20%。 DDoS 攻击分布&#xff08;按类型和手段&#xff09…

pytorch学习(十一)checkpoint

当训练一个大模型数据的时候&#xff0c;中途断电就可以造成已经训练几天或者几个小时的工作白做了&#xff0c;再此训练的时候需要从epoch0开始训练&#xff0c;因此中间要不断保存&#xff08;epoch&#xff0c;net&#xff0c;optimizer&#xff0c;scheduler&#xff09;等…

Java | Leetcode Java题解之第274题H指数

题目&#xff1a; 题解&#xff1a; class Solution {public int hIndex(int[] citations) {int left0,rightcitations.length;int mid0,cnt0;while(left<right){// 1 防止死循环mid(leftright1)>>1;cnt0;for(int i0;i<citations.length;i){if(citations[i]>mi…

Vue 3 实现左侧列表点击跳转滚动到右侧对应区域的功能

使用 Vue 3 实现左侧列表点击跳转到右侧对应区域的功能 1. 引言 在这篇博客中&#xff0c;我们将展示如何使用 Vue 3 实现一个简单的页面布局&#xff0c;其中左侧是一个列表&#xff0c;点击列表项时&#xff0c;右侧会平滑滚动到对应的内容区域。这种布局在很多应用场景中都…

金字塔思维:打造清晰有力的分析报告与沟通技巧

金字塔思维&#xff1a;打造清晰有力的分析报告与沟通技巧 在职场中&#xff0c;撰写一份条理清晰、逻辑严谨、说服力强的分析报告是每位职场人士必备的技能。然而&#xff0c;许多人在完成报告后常常感到思路混乱&#xff0c;表达不清。为了帮助大家解决这一问题&#xff0c;本…

VSCode部署Pytorch机器学习框架使用Anaconda(Window版)

目录 1. 配置Anaconda1.1下载安装包1. Anaconda官网下载2, 安装Anaconda 1.2 创建虚拟环境1.3 常用命令Conda 命令调试和日常维护 1.4 可能遇到的问题执行上述步骤后虚拟环境仍在C盘 2. 配置cuda2.1 查看显卡支持的cuda版本2.2 下载对应cuda版本2.3 下载对应的pytorch可能出现的…

学习React(状态管理)

随着你的应用不断变大&#xff0c;更有意识的去关注应用状态如何组织&#xff0c;以及数据如何在组件之间流动会对你很有帮助。冗余或重复的状态往往是缺陷的根源。在本节中&#xff0c;你将学习如何组织好状态&#xff0c;如何保持状态更新逻辑的可维护性&#xff0c;以及如何…

SQL 简单查询

目录 一、投影查询 1、指定特定列查询 2、修改返回列名查询 3、计算值查询 二、选择查询 1、使用关系表达式 2、使用逻辑表达式 3、使用 BETWEEN关键字 4、使用 IN关键字 5、使用 LIKE关键字 6、使用 IS NULL/ NOT NULL关键字 7、符合条件查询 三、聚合函数查询 一…