【C++】set/map(重点解析)
目录
一、关联式容器和序列式容器
二、C++中的键值对——pair
1.概念
2.定义
3.构造pair
三.set
1.construct构造
2.iterator迭代器
3.insert插入
4.erase删除
5.find查找
6.lower_bound和upper_bound
7.count
四.multiset
五.map
1.insert
2.operator[]
一、关联式容器和序列式容器
关联式容器:如其名,关联式表现在其基于键值对(<key,value>结构)的概念,通过键(key)来唯一标识元素,主要包括set、map、multiset、multimap等,它具有如下特征:
- 内部使用二叉搜索树(通常是红黑树)或类似的数据结构来保持元素的有序性
- 插入删除查找等操作的平均时间复杂度是O(logN)
序列式容器: 基于线性结构,元素在容器中的位取决于插入的顺序,主要包括vector、list、deque、array等,插入删除查找的平均时间复杂度因容器而异,最坏情况下为O(N)
二、C++中的键值对——pair
1.概念
键值是一种数据结构,通常用于表示关联关系,由两部分组成,键(Key)和值(Value),两者紧密关联,例如名字——学号的对应模式,此时Key就为学号(int类型),Value为名字(String类型),排序以学号(键)为基准,同时每一个键都唯一对应一个值。
2.定义
pair是C++标准库中提供的一个简单实现,它包含在头文件<utility>中,STL中对于键值对的定义如下:
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){}
};
3.构造pair
事实上,若你想构造一个pair<int,string>类,可以有以下三种方法:
auto p1 = pair<int, string>(1, "ysh");
auto p2 = make_pair(2, "zyh");
auto p3 = pair<int, string>{ 3,"xx" };
在一个存储类型为<int,string>键值对的map中插入数据时,就可以这样写:
map<int, string> m;
m.insert(pair<int,string>(1,"ysh"));
m.insert(make_pair(2, "zyh"));
m.insert({ 3,"xx" });
//毫无疑问,直接用{}构造是最简单的
三.set
set是按照一定次序储存元素的容器,它存储的就是单一的元素,当然也可以看作key和value是相同的,都是类型T(这是方便和map对比,毕竟都是基于键值对的容器),特性如下:
- 每个value必须是唯一的,这对应了set的去重功能
- 底层是二叉搜索树(红黑树)实现的,对应了O(logN)的效率
1.construct构造
一般使用迭代器区间构造,如下使用vector迭代器来进行构造
set<int> s1;
vector<int> v = { 1,2,3,4,5 };
set<int> s2(v.begin(), v.end());//利用迭代区间
set<int> s3 = s2;//拷贝构造
2.iterator迭代器
由于set的底层是二叉搜索树,因此遍历set所使用的迭代器也是遵循中序遍历的,二叉搜索树的中序遍历是有序的,则set的begin()返回迭代器就是其中最小的值,而end()则是对应最大值。

同时还有一个需要注意的小点,二叉搜索树实际是三叉树,树的节点间通过指针相连,那么这里而言,删除一个节点,不会使其他节点的迭代器失效。类似不会失效的有List,但像vector这种顺序结构就会导致失效。
3.insert插入
set是不允许插入重复的键值的,因此插入有可能会失败, 同时还会返回对应位置迭代器,因此这里返回值为pair<iterator,bool>类型
- 如果插入值不存在,则插入成功,返回指向该位置的迭代器和true
- 如果插入值已经存在,则插入失败,返回指向已存在元素位置的迭代器和false
相同的值无法被插入,因此set可以应用于去重操作

4.erase删除

需要说明的是迭代器区间删除遵循的原则是 左闭右开 , 也就是说first对应的会被删除,而last对应的不会被删除,这里可以配合后续要讲的lower_bound和upper_bound使用
5.find查找
find用于在set中查找指定键值的元素,并返回指向该元素的迭代器,若元素不存在,则返回end()
值得注意的是std中本身也有find查找函数,不过该查找是根据迭代器遍历查找,也就是说其查找的效率是O(N),而set自带量身定制的find,该find根据二叉搜索树的规则进行查找,能达到O(logN)的效率,使用定制的显然更好
6.lower_bound和upper_bound
lower_bound返回的是大于等于参数的迭代器,而upper返回的是大于该参数的迭代器,注意不是一个大于一个小于,区别仅仅是有无取等,此两函数常用于区间的删除,例如:
vector<int> v{ 10,20,30,40,50,60,70,80,90,100 };
set<int> s(v.begin(), v.end());
//lower_bound找>=30的,即30
auto itlow = s.lower_bound(30);
//upper_bound找>50的,即60
auto itup = s.upper_bound(50);
//删除遵循左闭右开,即删除30,40,50
//60是开区间不用删除
s.erase(itlow, itup);
for (auto e : s)
{cout << e << " ";
}
cout << endl;

7.count

count实际是用来统计该值在set中出现的次数的,但set不允许插入重复的键值,因此只有可能有0和1两种返回值,计数更多用于multiset中,不过根据该特性,倒是能设计出一个很简单的检验一个值是否存在于set中,如下操作:

四.multiset
multiset与set唯一的不同点就在于其multi前缀上,这表明multiset是允许键值重复的,即可以包含多个键值相同的元素。
其余操作和set别无二致,不过需要注意的是erase一个有多个节点的值时,会一次性将所有节点全部删除,如下:

五.map
map同样作为关联式容器,这就是标准的存储键值对的容器了,它按照特定的次序(按照Key来比较)储存由键Key和值value组合而成的元素。
map本身和set相差不多,接下来只提及一些差异点。
1.insert
前文在pair讲究中就已讲到,插入键值对有很多方法,有以下三种,不过还是用{}构造最简单
map<string, string> m1;//空的m1.insert(pair<string, string>("sort", "排序"));//匿名对象
m1.insert(make_pair("apple", "苹果"));//使用make_pair函数
m1.insert({ "apple", "苹果" });// C++11 多参数隐式类型转换(构造函数支持)
其实在insert的官方讲解中就有一句,还可以使用[]来进行插入,接下来就进行[]的讲解

2.operator[]
方括号[] 有两种用法
读取或插入元素时
- 若指定的键存在于map中,则返回与该键相关联的值value的引用
- 若指定的键不存在map中,则会插入一个新的键值对,其键key就为[]内部的key,而键则为默认构造对应的默认值,并返回该默认值的引用
因此,方括号不仅是用于读取,还能进行插入操作
map<string, string> m1;//空的m1.insert(pair<string, string>("sort", "排序"));
m1.insert(make_pair("apple", "苹果"));
m1.insert({ "left", "左边" });
for (auto& kv : m1)
{cout << kv.first << ":" << kv.second << " ";
}
cout << endl;m1["right"];//right不存在,这是插入一个right(key)
m1["apple"] = "青苹果";//由于apple已经存在,这里是进行修改for (auto& kv : m1)
{cout << kv.first << ":" << kv.second << " ";
}
cout << endl;

最后,multimap和map和关系 与 multiset和set关系一致,这里就不多赘述了,本文结束
相关文章:
【C++】set/map(重点解析)
目录 一、关联式容器和序列式容器 二、C中的键值对——pair 1.概念 2.定义 3.构造pair 三.set 1.construct构造 2.iterator迭代器 3.insert插入 4.erase删除 5.find查找 6.lower_bound和upper_bound 7.count 四.multiset 五.map 1.insert 2.operator[] 一、…...
【算法篇】动态规划类(1)(笔记)
目录 一、理论基础 1. 大纲 2. 动态规划的解题步骤 二、LeetCode 题目 1. 斐波那契数 2. 爬楼梯 3. 使用最小花费爬楼梯 4. 不同路径 5. 不同路径 II 6. 整数拆分 7. 不同的二叉搜索树 一、理论基础 1. 大纲 动态规划,英文:Dynamic Programm…...
mysql学习教程,从入门到精通,SQL 约束(Constraints)(41)
在数据库设计中,约束(Constraints)用于确保数据的准确性和完整性。它们通过限制可以插入到数据库表中的数据类型来防止无效数据。SQL 中有几种常见的约束类型,包括主键约束(Primary Key)、外键约束…...
使用CSS3与JavaScript实现炫酷的3D旋转魔方及九宫格交换动效
文章目录 前言一、项目需求背景二、CSS3 3D基础知识介绍2.1 什么是CSS3 3D?2.2 主要使用的CSS属性 三、使用HTML和CSS搭建魔方结构四、让魔方动起来:CSS3动画五、九宫格数字交换的JavaScript实现5.1 九宫格布局5.2 随机交换数字 六、随机交换与相邻格子的…...
springboot项目通过maven的profile功能实现通过不同文件夹的方式来组织不同环境配置文件
写在前面 本文看下springboot项目如何通过文件夹的方式来组织不同环境配置文件。 1:正文 一般的我们写springboot项目时配置文件是这个样子的: appliction.yaml --> 通过spring.profiles.activexxx来激活某个指定后缀的配置文件 application-evn1…...
GAN(Generative Adversarial Nets)
GAN(Generative Adversarial Nets) 引言 GAN由Ian J. Goodfellow等人提出,是Ian J. Goodfellow的代表作之一,他还出版了大家耳熟能详的花书(Deep Learning深度学习),GAN主要的思想是同时训练两个模型,生成…...
linux下使用mpi求自然数和
搭建MPI并行计算环境,编写 MPI程序,求和 1 23....1 0000。 要求: 1.使用100个进程; 2.进程0计算1 2...100, 进程1计算101 102... 200, ..... 进程99计算9901 9902... 10000; 3.调用计时函数,分别输出每个进程的计算时间; 4.需使用MPI集群通信函数和同…...
WebGl学习使用attribute变量绘制一个水平移动的点
在WebGL编程中,attribute变量是一种特殊类型的变量,用于从客户端传递数据到顶点着色器。这些数据通常包括顶点的位置、颜色、纹理坐标等,它们是与每个顶点直接相关的信息。attribute变量在顶点着色器中声明,并且对于每个顶点来说都…...
机器学习四大框架详解及实战应用:PyTorch、TensorFlow、Keras、Scikit-learn
目录 框架概述PyTorch:灵活性与研究首选TensorFlow:谷歌加持的强大生态系统Keras:简洁明了的高层 APIScikit-learn:传统机器学习的必备工具实战案例 图像分类实战自然语言处理实战回归问题实战 各框架的对比总结选择合适的框架 1…...
linux源码安装slurm以及mung和openssl
一、源码安装munge 1、编译安装munge (1)下载munge地址:https://github.com/dun/munge/releases (2)解压编译安装: 1 2 3 4 5 6 7 8 创建/data目录 复制文件munge-0.5.15.tar.xz 到/data目录下 tar -Jx…...
分享蓝牙耳机A2DP音频卡顿原因及解决思路
背景 最近一直在更新博客,我觉得写博客有三个好处,一是很多东西时间久了就会忘,记下来方便自己以后回忆和总结,二是记下来可以加深自己对知识的理解,三是可以知识分享,方便他人。 言归正传,今天…...
Mac 下编译 libaom 源码教程
AV1 AV1是一种开放、免版税的视频编码格式,由开放媒体联盟(AOMedia)开发,旨在提供高压缩效率和优秀的视频质量。AV1支持多种分辨率,包括SD、HD、4K和8K,并适用于视频点播(VOD)、直播…...
【成品设计】基于Arduino平台的物联网智能灯
《基于Arduino平台的物联网智能灯》 整体功能: 这个任务中要求实现一个物联网智能灯。实际测试环境中要求设备能够自己创建一个热点,连接这个热点后能自动弹出控制界面(强制门户)。 功能点 基础功能 (60分) 要求作品至少有2个灯…...
安装和配置k8s可视化UI界面dashboard-1.20.6
安装和配置k8s可视化UI界面dashboard-1.20.6 1.环境规划2.初始化服务器1)配置主机名2)设置IP为静态IP3)关闭selinux4)配置主机hosts文件5)配置服务器之间免密登录6)关闭交换分区swap,提升性能7&…...
VLAN:虚拟局域网
VLAN:虚拟局域网 交换机和路由器协同工作后,将原先的一个广播域,逻辑上,切分为多个广播域。 第一步:创建VLAN [SW1]dispaly vlan 查询vlan VID(VLAN ID):用来区分和标定不同的vlan 由12位二进制构成 范围: 0-4…...
利用可解释性技术增强制造质量预测模型
概述 论文地址:https://arxiv.org/abs/2403.18731 本研究提出了一种利用可解释性技术提高机器学习(ML)模型性能的方法。该方法已用于铣削质量预测,这一过程首先训练 ML 模型,然后使用可解释性技术识别不需要的特征并去…...
FlexMatch: Boosting Semi-Supervised Learning with Curriculum Pseudo Labeling
FlexMatch: Boosting Semi-Supervised Learning with Curriculum Pseudo Labeling 摘要:引言:背景3 flexMatch3.1 Curriculum Pseudo Labeling3.2 阈值预热3.3非线性映射函数实验4.1 主要结果4.2 ImageNet上的结果4.3收敛速度加速4.4 消融研究5 相关工作摘要: 最近提出的Fi…...
Spring Cloud 3.x 集成eureka快速入门Demo
1.什么是eureka? Eureka 由 Netflix 开发,是一种基于REST(Representational State Transfer)的服务,用于定位服务(服务注册与发现),以实现中间层服务的负载均衡和故障转移ÿ…...
线性代数 矩阵
一、矩阵基础 1、定义 一组数按照矩形排列而成的数表;形似行列式,区别点是 矩阵行列式符号()或[]| |形状方阵或非方阵方阵本质数表数属性A|A|是A诸多属性中的一种维度m *n (m 与n可以相等也可以不相等)n*n 同型矩阵 若A、B两个矩阵都是mn 矩阵&#x…...
【C语言】使用结构体实现位段
文章目录 一、什么是位段二、位段的内存分配1.位段内存分配规则练习1练习2 三、位段的跨平台问题四、位段的应用五、位段使用的注意事项 一、什么是位段 在上一节中我们讲解了结构体,而位段的声明和结构是类似的,它们有两个不同之处,如下&…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)
HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...
docker详细操作--未完待续
docker介绍 docker官网: Docker:加速容器应用程序开发 harbor官网:Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台,用于将应用程序及其依赖项(如库、运行时环…...
进程地址空间(比特课总结)
一、进程地址空间 1. 环境变量 1 )⽤户级环境变量与系统级环境变量 全局属性:环境变量具有全局属性,会被⼦进程继承。例如当bash启动⼦进程时,环 境变量会⾃动传递给⼦进程。 本地变量限制:本地变量只在当前进程(ba…...
解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八
现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet,点击确认后如下提示 最终上报fail 解决方法 内核升级导致,需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...
Go 语言接口详解
Go 语言接口详解 核心概念 接口定义 在 Go 语言中,接口是一种抽象类型,它定义了一组方法的集合: // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的: // 矩形结构体…...
连锁超市冷库节能解决方案:如何实现超市降本增效
在连锁超市冷库运营中,高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术,实现年省电费15%-60%,且不改动原有装备、安装快捷、…...
STM32标准库-DMA直接存储器存取
文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA(Direct Memory Access)直接存储器存取 DMA可以提供外设…...
BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...
今日科技热点速览
🔥 今日科技热点速览 🎮 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售,主打更强图形性能与沉浸式体验,支持多模态交互,受到全球玩家热捧 。 🤖 人工智能持续突破 DeepSeek-R1&…...
OPENCV形态学基础之二腐蚀
一.腐蚀的原理 (图1) 数学表达式:dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一,腐蚀跟膨胀属于反向操作,膨胀是把图像图像变大,而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...


