当前位置: 首页 > 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;如下&…...

数据链路层的主要功能是什么

数据链路层&#xff08;OSI模型第2层&#xff09;的核心功能是在相邻网络节点&#xff08;如交换机、主机&#xff09;间提供可靠的数据帧传输服务&#xff0c;主要职责包括&#xff1a; &#x1f511; 核心功能详解&#xff1a; 帧封装与解封装 封装&#xff1a; 将网络层下发…...

高危文件识别的常用算法:原理、应用与企业场景

高危文件识别的常用算法&#xff1a;原理、应用与企业场景 高危文件识别旨在检测可能导致安全威胁的文件&#xff0c;如包含恶意代码、敏感数据或欺诈内容的文档&#xff0c;在企业协同办公环境中&#xff08;如Teams、Google Workspace&#xff09;尤为重要。结合大模型技术&…...

【C语言练习】080. 使用C语言实现简单的数据库操作

080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...

拉力测试cuda pytorch 把 4070显卡拉满

import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试&#xff0c;通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小&#xff0c;增大可提高计算复杂度duration: 测试持续时间&#xff08;秒&…...

select、poll、epoll 与 Reactor 模式

在高并发网络编程领域&#xff0c;高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表&#xff0c;以及基于它们实现的 Reactor 模式&#xff0c;为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。​ 一、I…...

Element Plus 表单(el-form)中关于正整数输入的校验规则

目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入&#xff08;联动&#xff09;2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...

基于TurtleBot3在Gazebo地图实现机器人远程控制

1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...

AGain DB和倍数增益的关系

我在设置一款索尼CMOS芯片时&#xff0c;Again增益0db变化为6DB&#xff0c;画面的变化只有2倍DN的增益&#xff0c;比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析&#xff1a; 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...

OD 算法题 B卷【正整数到Excel编号之间的转换】

文章目录 正整数到Excel编号之间的转换 正整数到Excel编号之间的转换 excel的列编号是这样的&#xff1a;a b c … z aa ab ac… az ba bb bc…yz za zb zc …zz aaa aab aac…; 分别代表以下的编号1 2 3 … 26 27 28 29… 52 53 54 55… 676 677 678 679 … 702 703 704 705;…...

高考志愿填报管理系统---开发介绍

高考志愿填报管理系统是一款专为教育机构、学校和教师设计的学生信息管理和志愿填报辅助平台。系统基于Django框架开发&#xff0c;采用现代化的Web技术&#xff0c;为教育工作者提供高效、安全、便捷的学生管理解决方案。 ## &#x1f4cb; 系统概述 ### &#x1f3af; 系统定…...