map和set的介绍和使用

news2024/11/19 19:36:53

文章目录

    • map和set
      • 关联式容器
      • 键值对
      • set
        • 介绍
        • 模板参数
      • map
        • 介绍
        • 模板参数
        • 为什么map支持下标访问
      • multiset
        • 介绍
      • multimap

map和set

关联式容器

我们在之前讲过STL的一些基础容器,例如vector,list,deque,forward_list等

这些其实统一都称为序列式容器,因为其底层都是线性的序列数据结构,而且存储的内容是元素本身

关联式容器也是存储数据的容器,不同的是,里面存储的是<key,value>的键值对,类似于我们之前讲的二叉搜索树的KV模型

键值对

键值对是我们用来表示一一对应关系的结构,包含key和value两个成员变量

key表示关键字,类似于字典中的单词,value表示具体的值,也就是字典中对应的具体释义

在C++中使用pair表示一对值,但并没有具体的对应关系,只是将这一对值进行了封装,可以读取和写入,当然pair也有一些非常有意思的内容,当我们观察其源码时可以看出

这里给出SGI-STL对pair的定义

template<class T1, class T2>
struct pair
{
	typedef T1 first_type;
	typedef T2 second_type;
   	
    T1 first;
    T2 second;
    
    pair() // 构造
        :first(T1())
        ,second(T2())
    {}
    
    pair(const T1& a, const T2& b) // 拷贝构造
    	:first(a)
    	,second(b)
    {}
};

set

介绍

set的文档

set直接翻译成中文是集合,而他与数学意义上的集合也有不同的地方,set是要求有序的,其次set中的元素不能被修改,元素是const的,但是允许插入删除

set的有序是可以自行定义升序或者降序的,默认是按照小于排序(升序),不允许重复值

set容器通过key访问单个元素的速度比unordered_set慢,但是都允许根据顺序对子集直接迭代

set在底层是使用二叉搜索树的红黑树实现的

set的底层实际上也是有pair的,只不过是<value,value>的形式,在插入元素时,只需要插入value即可

set查找的时间复杂度是 log ⁡ 2 n \log_2n log2n

模板参数

屏幕截图 2024-03-13 172738.png

第一行的T是存放元素的类型,实际是存在底层的<value,value>键值对

第二行的Compare是仿函数,用于确定是升序还是降序,默认为升序

第三行是一个空间配置器

这里其他的内容参考set的官方文档即可

map

介绍

map文档

map是关联容器,直接翻译称为映射,是我们之前讲的二叉搜索树的KV模型,他存储的元素是一个有key和value构成的有序对

在map中,key是唯一的,用于标识value

STL中使用typedef来减少长度

typedef pair<const key, T> value_type;

map内部是对key值排序,默认是升序,他对单个元素的访问速度比unordered_map慢,但是map允许根据顺序对元素进行直接迭代

map支持下标访问,可以直接找到与key对应的value,这里的实现让人赞叹

map的底层是由红黑树实现的,我们在之后的内容里也会使用红黑树实现set和map

模板参数

image.png

Key是键值对中的key,T对应的是value,后面分别是仿函数和空间配置器

需要注意的是,这里的map::key_type和map::mapped_type是typedef出的

image.png

这里我们注意到一个细节,在定义pair的时候,first被const了,说明key值是不能被修改的

为什么map支持下标访问

我们看map对方括号的重定义

image.png

image.png

也就是说他内部是这样实现的

mapped_type& operator[] (const key_type& k)
{
    return *((this->insert(make_pair(k,mapped_type())).first)).second;
}

这里看上去比较复杂,我们剥洋葱一样的来看

第一层是调用了map的insert插入函数,我们来看insert的定义

image.png

这里调用的是单参数的insert,value_type是一个pair对象,我们可以通过make_pair的名称就知道,他是用于构建pair对象的

insert的返回值是也一个pair对象,first是迭代器,bool是用来表示插入是否成功,如果成果,first指向的就是新pair,如果失败first指向的就是已经存在的pair

然后来看看make_pair函数的定义

image.png

这里就和我们设想的是一样的了,用于构建pair

然后我们看回去,他的参数有两个k和mapped_type(),这里的mapped_type实际上就是value的构造函数,因为在我们插入时只指定了key,没有value,因此直接调用value的构造函数即可

然后构造完成之后,返回的pair被插入到map中,返回值就是pair<iterator, bool>,这时我们取第一个iterator,表示指向插入的pair(无论是否成功插入,都会指向),然后再取第二个值,也就是插入之后的pair的value

返回值也就是pair之中的value

这里有个细节,重定义的返回值是引用的,说明可以支持赋值操作,初始化操作等

例如

map<string, string> m;
m["加"] = "plus";
m["减"] = "sub";
m["加"] = "add";
m["乘"];

总结一下就是分四步

  1. 用<key,value_type()>构建一个键值对,调用inset()插入到map中
  2. 如果key存在,插入失败,返回key所在位置的迭代器
  3. 如果key不存在,插入成功,返回新插入元素位置的迭代器
  4. 返回插入的键值对的引用

multiset

介绍

multiset文档

multiset与set类似,其中的元素是可以重复的,他的底层也是红黑树

红黑树是二叉搜索树,我们可以先按照二叉搜索树理解,他为什么也可以有序呢

实际上是因为他的插入规则是确定的,例如小于在左子树,大于等于在右子树,这样他的中序遍历就依然是有序的

multimap

multimap文档

multimap与map类似,需要注意的是,multimap不支持下标访问了,其他都是相同的

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

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

相关文章

Script标签中 defer 和 async 属性的区别

script 标签中 defer & async 属性 如果我们注意过 html 中的 <script> 标签&#xff0c;就会发现在有的加载 JavaScript 文件的 <script src"https://code.jquery.com/jquery-3.7.1.min.js" defer></script>这里就探讨一下 script 标签上的…

[AutoSar]BSW_Com013 CAN TP 模块配置

目录 关键词平台说明一、缩写对照表二、Functional Description&#xff08;vector&#xff09;2.1 Asynchronous and Synchronous behavior of CanTp_Transmit2.1.1 asynchronous 2.1.2 synchronous2.2 Separation Time by Application 三、CanTpChannels3.1 接收端3.2 发送端…

【Web】浅聊Java反序列化之C3P0——URLClassLoader利用

目录 前言 C3P0介绍 回归本源——序列化的条件 利用链 利用链分析 入口——PoolBackedDataSourceBase#readObject 拨云见日——PoolBackedDataSourceBase#writeObject 综合分析 EXP 前言 这条链最让我眼前一亮的就是对Serializable接口的有无进行了一个玩&#xff0c…

day42 动态规划part4

先遍历物品还是先遍历背包二刷再考虑吧。累了&#xff0c;不想停留太久。 背包问题 二维 &#xff08;卡码网题目&#xff09; 各种解释&#xff1a; 要理解的是这个表格每一个格子都是当前所处情况的最大价值&#xff0c;我们用已经推导出的最大价值来推导当前情况的最大价值…

2.案例、鼠标时间类型、事件对象参数

案例 注册事件 <!-- //disabled默认情况用户不能点击 --><input type"button" value"我已阅读用户协议(5)" disabled><script>// 分析&#xff1a;// 1.修改标签中的文字内容// 2.定时器// 3.修改标签的disabled属性// 4.清除定时器// …

GUROBI之数学启发式算法Matheuristics

参考运小筹的帖子&#xff1a;优化求解器 | Gurobi 数学启发式算法&#xff1a;参数类型与案例实现 - 知乎 (zhihu.com) 简言之&#xff0c;数学启发式是算法就是数学规划和启发式算法的融合&#xff0c;与元启发式算法相比&#xff0c;数学启发式算法具有更强的理论性。 在GUR…

WEB区块链开发组件 - KLineChart

当我们开发区块链的时候&#xff0c;实现K线可能大家会想到EChart&#xff0c;但是EChart做可能需要耗费大量工作量&#xff0c;实现出来的功能估计也是牵强着用。 这时候&#xff0c;我们可能网上会搜索到TradingView,可是这个组件虽然功能非常强大&#xff0c;但是还是要费事…

视觉图像处理和FPGA实现第三次作业--实现一个加法器模块

一、adder模块 module adder(ina, inb, outa); input [5:0] ina ; input [5:0] inb ; output [6:0] outa ;assign outa ina inb; endmodule二、add模块 module add(a,b,c,d,e); input [5:0] a ; input [5:0] b ; input [5:…

Matlab R2021a安装教程(附带免费安装包)

作者&#xff1a;翟天保Steven 版权声明&#xff1a;著作权归作者所有&#xff0c;商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处 Matlab简介 Matlab是一种高级技术计算语言和交互式环境&#xff0c;用于算法开发、数据可视化和数值计算。它集成了数学、工程和科…

unity中实现场景跳转

1&#xff0c;第一步创建2个场景&#xff08;右键资源窗口&#xff0c;名字这里我取的1111和2222&#xff09; 2.添加跳转按钮&#xff08;双击其中一个场景并添加按钮&#xff09; 3.编辑按钮的文字&#xff08;将原本的按钮打开点击里面的text&#xff0c;就可以在右边编辑文…

MySQL 多种日期处理函数介绍

MySQL 提供了多种日期处理函数&#xff0c;用于处理和操作日期和时间数据。这些函数可以帮助你执行如日期计算、时间转换、格式化输出等操作。以下是一些常用的 MySQL 日期处理函数及其用法&#xff1a; 日期和时间格式化函数 1. **DATE_FORMAT()**&#xff1a;将日期或时间戳格…

AI壁纸号一周增加上千粉丝,轻松变现的成功案例分享

前言 随着AI绘画技术的发展&#xff0c;传统的互联网副业壁纸号在新的技术加持下迎来了第二春。本文将分享一位壁纸号创作者的成功案例&#xff0c;并为大家提供创作门槛和硬件要求等相关信息。 该项目的创作门槛极低&#xff0c;基本上可以由AI完成内容创作。不过&#xff0…

使用python实现一个dicom影像解析入库程序demo

简介 DICOM&#xff08;Digital Imaging and Communications in Medicine&#xff09;是医学图像和相关信息的国际标准。它定义了医学影像的格式和通信协议&#xff0c;使得不同设备和系统之间可以交换和共享医学图像和相关数据&#xff0c;如CT扫描、MRI图像、超声波图像等。…

代码随想录算法训练营第七天| 454.四数相加II、383.赎金信、15.三数之和、18.四数之和

系列文章目录 目录 系列文章目录454.四数相加II使用HashMap法 383.赎金信哈希解法&#xff08;数组&#xff09; 15.三数之和双指针法 18.四数之和双指针法 454.四数相加II 题解&#xff1a;该题和1.两数之和的方法是一样的&#xff0c;这个题的难点在于key和value分别是什么。…

发那科数控机床FanucCNC(NCGuide)仿真模拟器配置和数据采集测试

开发日记3.12 此篇用于记录发那科数控机床(Fanuc CNC)采集程序开发中&#xff0c;用虚拟机做测试时&#xff0c;虚拟机的配置和使用以支持采集软件开发和测试。 配置虚拟机使用仿真软件 下载VMware15 「链接&#xff1a;https://pan.xunlei.com/s/VNsl9Gmb14ANBiiNlsT7vA2LA…

Day15 面向对象进阶——接Day14

Day15 面向对象进阶——接Day14 文章目录 Day15 面向对象进阶——接Day14一、访问修饰符二、Object三、深入String的equals()方法四、final 一、访问修饰符 1、含义&#xff1a;修饰类、方法、属性&#xff0c;定义使用的范围 2、经验&#xff1a; 2.1.属性一般使用private修…

springboot3 打包报错32-bit architecture x86 unsupported或者 returned non-zero result

springboot3 打包异常情况处理记录 在测试springboot3 native打包时候遇到的异常&#xff0c;百度和谷歌上方法都无法解决我的问题&#xff0c;最后记录一下我最后的原因和解决方案。 前置要求&#xff1a;自己处理好vs的相关内容后 报错一&#xff1a; [1/7] Initializing…

Vue3 前端生成随机id( 生成 UUID )

效果展示 封装工具&#xff08;代码展示&#xff09; 重新创建一个文件**/utils/someTools.js**&#xff0c;并在里面写入如下代码。 function Tools() {}Tools.prototype.guid function () {return xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx.replace(/[xy]/g, function (c) {v…

Android SDK 开发 云托管

开发SDK,拒绝重复造轮子。 本文陈述两种SDK开发方式&#xff0c;第一种AAR方式&#xff1b;第二种远程依赖方式。 具体步骤分为&#xff1a; 一、如何开发SDK&#xff1f; 二、如何打包AAR&#xff1f; 三、如何打包AAR&#xff1f; 四、如何进行SDK远程托管&#xff1f; 五、如…

工业物联网平台在水务环保、暖通制冷、电力能源等行业的应用

随着科技的不断发展&#xff0c;工业物联网平台作为连接物理世界与数字世界的桥梁&#xff0c;正逐渐成为推动各行业智能化转型的关键力量。在水务环保、暖通制冷、电力能源等行业&#xff0c;工业物联网平台的应用尤为广泛&#xff0c;对于提升运营效率、降低能耗、优化管理等…