当前位置: 首页 > news >正文

【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. 大纲 动态规划&#xff0c;英文&#xff1a;Dynamic Programm…...

mysql学习教程,从入门到精通,SQL 约束(Constraints)(41)

在数据库设计中&#xff0c;约束&#xff08;Constraints&#xff09;用于确保数据的准确性和完整性。它们通过限制可以插入到数据库表中的数据类型来防止无效数据。SQL 中有几种常见的约束类型&#xff0c;包括主键约束&#xff08;Primary Key&#xff09;、外键约束&#xf…...

使用CSS3与JavaScript实现炫酷的3D旋转魔方及九宫格交换动效

文章目录 前言一、项目需求背景二、CSS3 3D基础知识介绍2.1 什么是CSS3 3D&#xff1f;2.2 主要使用的CSS属性 三、使用HTML和CSS搭建魔方结构四、让魔方动起来&#xff1a;CSS3动画五、九宫格数字交换的JavaScript实现5.1 九宫格布局5.2 随机交换数字 六、随机交换与相邻格子的…...

springboot项目通过maven的profile功能实现通过不同文件夹的方式来组织不同环境配置文件

写在前面 本文看下springboot项目如何通过文件夹的方式来组织不同环境配置文件。 1&#xff1a;正文 一般的我们写springboot项目时配置文件是这个样子的&#xff1a; appliction.yaml --> 通过spring.profiles.activexxx来激活某个指定后缀的配置文件 application-evn1…...

GAN(Generative Adversarial Nets)

GAN(Generative Adversarial Nets) 引言 GAN由Ian J. Goodfellow等人提出&#xff0c;是Ian J. Goodfellow的代表作之一&#xff0c;他还出版了大家耳熟能详的花书&#xff08;Deep Learning深度学习&#xff09;&#xff0c;GAN主要的思想是同时训练两个模型&#xff0c;生成…...

linux下使用mpi求自然数和

搭建MPI并行计算环境&#xff0c;编写 MPI程序&#xff0c;求和 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编程中&#xff0c;attribute变量是一种特殊类型的变量&#xff0c;用于从客户端传递数据到顶点着色器。这些数据通常包括顶点的位置、颜色、纹理坐标等&#xff0c;它们是与每个顶点直接相关的信息。attribute变量在顶点着色器中声明&#xff0c;并且对于每个顶点来说都…...

机器学习四大框架详解及实战应用:PyTorch、TensorFlow、Keras、Scikit-learn

目录 框架概述PyTorch&#xff1a;灵活性与研究首选TensorFlow&#xff1a;谷歌加持的强大生态系统Keras&#xff1a;简洁明了的高层 APIScikit-learn&#xff1a;传统机器学习的必备工具实战案例 图像分类实战自然语言处理实战回归问题实战 各框架的对比总结选择合适的框架 1…...

linux源码安装slurm以及mung和openssl

一、源码安装munge 1、编译安装munge &#xff08;1&#xff09;下载munge地址&#xff1a;https://github.com/dun/munge/releases &#xff08;2&#xff09;解压编译安装&#xff1a; 1 2 3 4 5 6 7 8 创建/data目录 复制文件munge-0.5.15.tar.xz 到/data目录下 tar -Jx…...

分享蓝牙耳机A2DP音频卡顿原因及解决思路

背景 最近一直在更新博客&#xff0c;我觉得写博客有三个好处&#xff0c;一是很多东西时间久了就会忘&#xff0c;记下来方便自己以后回忆和总结&#xff0c;二是记下来可以加深自己对知识的理解&#xff0c;三是可以知识分享&#xff0c;方便他人。 言归正传&#xff0c;今天…...

Mac 下编译 libaom 源码教程

AV1 AV1是一种开放、免版税的视频编码格式&#xff0c;由开放媒体联盟&#xff08;AOMedia&#xff09;开发&#xff0c;旨在提供高压缩效率和优秀的视频质量。AV1支持多种分辨率&#xff0c;包括SD、HD、4K和8K&#xff0c;并适用于视频点播&#xff08;VOD&#xff09;、直播…...

【成品设计】基于Arduino平台的物联网智能灯

《基于Arduino平台的物联网智能灯》 整体功能&#xff1a; 这个任务中要求实现一个物联网智能灯。实际测试环境中要求设备能够自己创建一个热点&#xff0c;连接这个热点后能自动弹出控制界面&#xff08;强制门户&#xff09;。 功能点 基础功能 (60分) 要求作品至少有2个灯…...

安装和配置k8s可视化UI界面dashboard-1.20.6

安装和配置k8s可视化UI界面dashboard-1.20.6 1.环境规划2.初始化服务器1&#xff09;配置主机名2&#xff09;设置IP为静态IP3&#xff09;关闭selinux4&#xff09;配置主机hosts文件5&#xff09;配置服务器之间免密登录6&#xff09;关闭交换分区swap&#xff0c;提升性能7&…...

VLAN:虚拟局域网

VLAN:虚拟局域网 交换机和路由器协同工作后&#xff0c;将原先的一个广播域&#xff0c;逻辑上&#xff0c;切分为多个广播域。 第一步:创建VLAN [SW1]dispaly vlan 查询vlan VID&#xff08;VLAN ID&#xff09;:用来区分和标定不同的vlan 由12位二进制构成 范围: 0-4…...

利用可解释性技术增强制造质量预测模型

概述 论文地址&#xff1a;https://arxiv.org/abs/2403.18731 本研究提出了一种利用可解释性技术提高机器学习&#xff08;ML&#xff09;模型性能的方法。该方法已用于铣削质量预测&#xff0c;这一过程首先训练 ML 模型&#xff0c;然后使用可解释性技术识别不需要的特征并去…...

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&#xff1f; Eureka 由 Netflix 开发&#xff0c;是一种基于REST&#xff08;Representational State Transfer&#xff09;的服务&#xff0c;用于定位服务&#xff08;服务注册与发现&#xff09;&#xff0c;以实现中间层服务的负载均衡和故障转移&#xff…...

线性代数 矩阵

一、矩阵基础 1、定义 一组数按照矩形排列而成的数表&#xff1b;形似行列式&#xff0c;区别点是 矩阵行列式符号()或[]| |形状方阵或非方阵方阵本质数表数属性A|A|是A诸多属性中的一种维度m *n (m 与n可以相等也可以不相等)n*n 同型矩阵 若A、B两个矩阵都是mn 矩阵&#x…...

【C语言】使用结构体实现位段

文章目录 一、什么是位段二、位段的内存分配1.位段内存分配规则练习1练习2 三、位段的跨平台问题四、位段的应用五、位段使用的注意事项 一、什么是位段 在上一节中我们讲解了结构体&#xff0c;而位段的声明和结构是类似的&#xff0c;它们有两个不同之处&#xff0c;如下&…...

[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解

突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 ​安全措施依赖问题​ GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...

【杂谈】-递归进化:人工智能的自我改进与监管挑战

递归进化&#xff1a;人工智能的自我改进与监管挑战 文章目录 递归进化&#xff1a;人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管&#xff1f;3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...

可靠性+灵活性:电力载波技术在楼宇自控中的核心价值

可靠性灵活性&#xff1a;电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中&#xff0c;电力载波技术&#xff08;PLC&#xff09;凭借其独特的优势&#xff0c;正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据&#xff0c;无需额外布…...

DAY 47

三、通道注意力 3.1 通道注意力的定义 # 新增&#xff1a;通道注意力模块&#xff08;SE模块&#xff09; class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明

AI 领域的快速发展正在催生一个新时代&#xff0c;智能代理&#xff08;agents&#xff09;不再是孤立的个体&#xff0c;而是能够像一个数字团队一样协作。然而&#xff0c;当前 AI 生态系统的碎片化阻碍了这一愿景的实现&#xff0c;导致了“AI 巴别塔问题”——不同代理之间…...

新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案

随着新能源汽车的快速普及&#xff0c;充电桩作为核心配套设施&#xff0c;其安全性与可靠性备受关注。然而&#xff0c;在高温、高负荷运行环境下&#xff0c;充电桩的散热问题与消防安全隐患日益凸显&#xff0c;成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...

【python异步多线程】异步多线程爬虫代码示例

claude生成的python多线程、异步代码示例&#xff0c;模拟20个网页的爬取&#xff0c;每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程&#xff1a;允许程序同时执行多个任务&#xff0c;提高IO密集型任务&#xff08;如网络请求&#xff09;的效率…...

JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作

一、上下文切换 即使单核CPU也可以进行多线程执行代码&#xff0c;CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短&#xff0c;所以CPU会不断地切换线程执行&#xff0c;从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...

学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”

2025年#高考 将在近日拉开帷幕&#xff0c;#AI 监考一度冲上热搜。当AI深度融入高考&#xff0c;#时间同步 不再是辅助功能&#xff0c;而是决定AI监考系统成败的“生命线”。 AI亮相2025高考&#xff0c;40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕&#xff0c;江西、…...

Angular微前端架构:Module Federation + ngx-build-plus (Webpack)

以下是一个完整的 Angular 微前端示例&#xff0c;其中使用的是 Module Federation 和 npx-build-plus 实现了主应用&#xff08;Shell&#xff09;与子应用&#xff08;Remote&#xff09;的集成。 &#x1f6e0;️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...