C++学习之map和set

news2024/11/27 6:26:14

目录

一,什么是map和set

二,set的使用 

插入

键值对

删除(erase)与查找

lowerbound与upperbound

equal_range

multiset

三,map的使用

insert

 查找

删除

重载[ ]

​编辑


一,什么是map和set

C++中的Map和Set都是关联式容器,用于存储数据的集合。

所谓关联式容器,不同于序列式容器,序列是容器是一种线性结构用来存放数据,而关联式容器,虽然也是存放数据的,但是他们的数据与存放的key值,是一一对应的,利用键值查找数据或修改数据。

它们之间的区别在于:

Map是一组键值对的结构,类似于JSON对象。每个元素都是由一个关键字和一个值组成。关键字起到索引的作用,值则表示与索引相关联的数据。Set对象类似于数组,且成员的值都是唯一的.
Map可以通过get方法获取值,而set不能因为它只有值.


Set的迭代器是const的,不允许修改元素的值;map允许修改value,但不允许修改key.

在C++中,Map和Set都是STL(标准模板库)的一部分。它们都有自己的特定语法和用法。例如,要使用Map,您需要包含头文件<map>,而要使用Set,您需要包含头文件<set>。这些容器都提供了许多有用的方法,例如插入、删除、查找等等。希望这些信息能够帮助你更好地理解它们之间的区别。

对于map和set,我们首先要知道他们的底层就是一颗搜索二叉树,因此对于他们的功能和性质我们要知道会有限制以及搜索树特殊的性质,

二,set的使用 

可以看到库里给出的实现,首先只有一个数据的类型模板T,之后就是仿函数compare用来比较,一个空间配置器为我们开辟对应的空间。

因为set只有一个参数,故此它的key也就是它的数据,也就是一个key模型。

我们再来看看它的内容:

成员函数构造与析构,这里需要提到的一点是,对于节点的拷贝与释放,代价是比较大的,因此析构与拷贝构造需要我们去好好使用。

之后的迭代器,容量等我们在学习STL其他容器大致也能明白如何使用。

对于任何一个数据模型,最为重要的功能无非是增,删,查,改,这四个功能,但底层是搜索树,这是不存在修改的,因为set只是一个单纯的key模型。

插入

库里给出了三种插入的方式,直接插入,利用迭代器确定位置插入(谨慎使用,可能会破坏树结构),利用迭代器插入一连串的数据。一般我们就是用第一个插入数据。

我们简单的使用一下:

void test1()
{
	set<int> s;
	s.insert(2);
	s.insert(1);
	s.insert(5);
	s.insert(4);
	s.insert(9);
    s.insert(4);
	//迭代器遍历
	set<int>::iterator it = s.begin();
	while (it != s.end())
	{
		cout << *it<<" ";
		it++;
	}
	cout << endl;
}

首先插入元素后,利用迭代器遍历插入的数据我们发现书记已经排好序了,其次相同的数据只会插入一个,这与我们之前学习到的搜索二叉树一样,而这里的遍历,实际上就是走了一个中序遍历,且在相同值插入的时候会判断直接返回。

键值对

其次对于函数的返回值,也是一个我们没见过的pair,这个其实就是一个键值对,在这里,封装了两个数据,我们来看看它定义:

一共封装了两个数据以及它们对应的模板参数,一个first,一个second分别代表了两个数据,

利用这种方式函数可以返回两个数据。而这里对于我们的set,first就是一个迭代器表示这个节点,second是一个bool值,表示是否插入成功。

pair<set<int>::iterator, bool> p = s.insert(5);//利用pair p接收返回值

删除(erase)与查找

删除的方式与插入的方式类型,我们可以直接给值,给迭代器位置,给迭代器区间都可以。

而这里就可以与find配合起来,find的返回值就是迭代器类型。

其次就是比较特殊的两个接口函数:

lowerbound与upperbound

我们可以直接看看库里给的测试:

 可以看到,通过lowerbound和upperbound的返回值,我们删除了某一段迭代器,这里itlower返回30,upperbound返回70,迭代器区间就是[30~70],实际上,upperbound返回的是一个比参数大的迭代器,lowerbound返回的是比参数小于或等于的迭代器。通过这种方式我们可以找迭代器区间,返回这个区间是,删除函数接收到删除的是[30~70)区间的迭代器。

类似的区间还有

equal_range

可以看到equal_range的返回值是一个pair,里面放封装了两个迭代器,根据测试,可以看到第一个是一个比参数大于等于的迭代器,第二个是比参数大于的迭代器。

multiset

了解完set之后,库里其实还有一个与set基本一致的结构-multiset,所谓的multiset本质上与set的区别就是multiset可以存放相等的数据:

void test1()
{
	multiset<int> s;
	s.insert(2);
	s.insert(1);
	s.insert(1);
	s.insert(1);
	s.insert(5);
	s.insert(4);
	s.insert(9);

	//迭代器遍历
	multiset<int>::iterator it = s.begin();
	while (it != s.end())
	{
		cout << *it<<" ";
		it++;
	}
	cout << endl;
}

 对于寻找,若有多个一样的,返回第一个找到的val的节点。

且此时的mulyiset对上述的接口equal_range与count等函数接口配合使用可以对相同的元素更加灵活的操作。

三,map的使用

 首先来看看map的定义,模板参数中,给了key值的类型模板,数据T的类型模板,利用仿函数实现的一个比较,一个空间配置器用来开辟空间。

与set的区别是多了一个数据类型,对于set来说是key模型,那么对于map来说就是一个key_value模型,通过键值key来获取对应的数据value。

之后便是与set如出一辙的构造析构,迭代器等基本的实现,我们还是主要来看看增删查改。

insert

 map的insert与set基本近似,但是我们这里不是两个数据模板参数吗?为什么这里传入参数只有一个,且类型为value_type,此时我们需要在求助于库看一看:

这里的valuetypr实际上是key_type与mapped_type两个类型参数封装起来的pair,即这个value —_type本质上是一个pair类。

其次对于这里的pair是很灵活的,pair是支持带参数的拷贝构造的,这奥我们的类型能初始化参数,那么类型即使看起来不一样但同时初始化字符串。

除了一个个显式实例化pair,我们自己还可以直接用make_pair传入参数自动生成对应的pair对象,并且在传入参数时,不需要再一个个的显示类型实例化,直接传入pair匿名对象。

其次插入的返回值也是一个pair对象,这里第一个表示该迭代器,第二个表示是否插入,其次迭代器中存放的也是pair,第一个表示key,第二个表示value。

之后通过map我们轻松的就可以创建一个字典模型:

void test2()
{
	map<string, string> dictionary;
	dictionary.insert(pair<string, string>("a", "abanden"));
	dictionary.insert(pair<string, string>("b", "bacteria"));
	dictionary.insert(pair<string, string>("c", "cabbage"));
	dictionary.insert(pair<const char*, const char*>("d", "data"));
	dictionary.insert(make_pair("e", "erase"));
	map<string, string>::iterator it = dictionary.begin();
	while (it != dictionary.end())
	{
		cout <<(*it).first <<" ";
		cout << (*it).second << endl;
		it++;
	}
	cout << endl;
}

 查找

 可以清晰地看到find的返回值是迭代器,参数是key,即通过键值找对应的value.

删除

 删除是通过迭代器或者key值删除的,也是可与find配合使用。

重载[ ]

对于这里的重载[ ],这里我们自己刚开始看可能搞不懂,我们可以仔细观察对于重载operator,它的本质就是insert(key)的返回值pair中的迭代器(insert().first)的second,即就是我们的value值,它是通过这种方式来访问key值处的value。

通过重载[ ],我们直接访问到key处的value,查找更加简单方便。

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

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

相关文章

云闪付app拉新好做吗?地推和网推百搭拉新项目申请渠道

云闪付拉新可通过”聚量推客“申请 云闪付是银联出的支付平台&#xff0c;每年在拉新市场的预算较高&#xff0c;比较适合地推和网推做项目搭配&#xff0c;只需要完成一次动账即可结算 我们上了两个版本的云闪付项目&#xff0c;下图展示 也有更多的其它地推和网推拉新项目可…

【通关选择】upload-labs通关攻略(大全)

前提条件&#xff1a; 1.文件能够成功上传到服务器 2.攻击者能够知道文件的上传路径 upload-labs靶场 Pass-01&#xff08; 前端验证&#xff09; 三种方法解决思路 1.禁用客户端JavaScript弹窗 2.通过burp抓包&#xff0c;修改后缀名 3.f12删除return filecheck&#xff0…

树专题 —— 二叉搜索树和中序遍历

大家好&#xff0c;我是 方圆。我准备把树写成一个专题&#xff0c;包括二叉搜索树、前序、中序、后序遍历以及红黑树&#xff0c;我也想试试能不能将红黑树写好。 本篇是关于二叉搜索树&#xff0c;也是所有后续学习的基础&#xff0c;其中会涉及前序、中序、后序遍历&#x…

外卖系统的数据管理和隐私保护应该如何进行?

1. 数据管理 外卖系统处理大量用户数据&#xff0c;包括个人信息、订单记录、支付信息等。以下是一些数据管理的最佳实践&#xff1a; 合规性与透明度&#xff1a;确保你的数据收集、存储和处理符合相关法规&#xff0c;例如GDPR&#xff08;通用数据保护条例&#xff09;。同…

网络安全防御体系构建思路

前言 在某一天的深夜&#xff0c;作为安全从业人员&#xff0c;穿着大裤衩子&#xff0c;坐在门前&#xff0c;点燃一根烟&#xff08;画面自己想象&#xff09;开始思考企业如何打造自己的安全体系&#xff0c;虽然这不是作为月薪3k该考虑的问题&#xff0c;但是毕竟当初笔者…

element的表单校验正常手机号码以及输入框填写“不详”的情况

element的表单校验正常手机号码以及输入框填写“不详”的情况 <el-col :span"6"><el-form-item label"手机号码" prop"phoneNumber" class"grid-content bg-purple"><el-input v-model"testForm.phoneNumber&quo…

Linux环境下的SVN服务器搭建并结合内网穿透实现远程连接

文章目录 前言1. Ubuntu安装SVN服务2. 修改配置文件2.1 修改svnserve.conf文件2.2 修改passwd文件2.3 修改authz文件 3. 启动svn服务4. 内网穿透4.1 安装cpolar内网穿透4.2 创建隧道映射本地端口 5. 测试公网访问6. 配置固定公网TCP端口地址6.1 保留一个固定的公网TCP端口地址6…

第四章 Web服务器(1)

1.www简介 Web网络服务也叫WWW(World Wide Web 全球信息广播)万维网服务&#xff0c;一般是指能够让用户通过浏览器访问到互联网中文档等资源的服务 Web 网络服务是一种被动访问的服务程序&#xff0c;即只有接收到互联网中其他主机发出的请求后才会响应&#xff0c;最…

LINQ to SQL系列三 使用DeferredLoadingEnabled,DataLoadOption指定加载选项

介绍linq to sql 的 DataContext类DeferredLoadingEnabled属性使用,以及DataLoadOptions限定加载相关表数据的LoadWith和AssociateWith方法。 本文中举例用到的数据模型如下: Student和Class之间是多对一关系,Student和Course之间是多对多关系。 DataContext的DeferredLo…

使用oracle虚拟机添加新硬盘

1、关闭运行的虚拟机后配置 单击选择要配置的oracle虚拟机&#xff0c;单击设置–>存储—>控制器&#xff0c;单击添加虚拟硬盘图标。 2、配置硬盘 单击“创建”&#xff0c;单击“下一步”&#xff0c;选择需要创建的虚拟硬盘大小&#xff0c;完成创建。 完成创建后…

基于SpringBoot+Redis的前后端分离外卖项目-苍穹外卖(一)

熟悉项目环境 1. 苍穹外卖项目介绍1.1 项目介绍1.2 技术选型 2. 开发环境搭建2.1 前端环境2.2 后端环境搭建2.3 Git版本控制2.4 nginx反向代理和负载均衡 3.登录功能4. Swagger4.1 介绍4.2 使用步骤4.3 常用注解 1. 苍穹外卖项目介绍 1.1 项目介绍 苍穹外卖是专门为餐饮企业&…

SRC | CORS跨资源共享漏洞

CORS跨资源共享 跨源资源共享 (CORS) 是一种浏览器机制&#xff0c;允许网页使用来自其他页面或域的资产和数据。 大多数站点需要使用资源和图像来运行它们的脚本。这些嵌入式资产存在安全风险&#xff0c;因为这些资产可能包含病毒或允许服务器访问黑客。 CORS响应头 CORS通…

C-DS二叉树_另一棵树的子树

Description 给你两棵二叉树tree1和tree2,检验tree1中是否包含和tree2具有相同结构和结点值的子树。如果存在,输出true;否则,输出false。 Input 第一行输入t,表示有t个测试样例。 第二行首先输入n1,接着输入n1个整数,表示二叉树tree1。 第三行首先输入n2,接着输入n…

Keras人工智能神经网络 Classifier 分类 神经网络搭建

前期我们分享tensorflow以及pytorch时&#xff0c;分享过tensorflow以及pytorch的分类神经网络的搭建步骤&#xff0c;在哪里我们使用的训练集是mnist&#xff0c;同样Keras分类神经网络的搭建&#xff0c;我们同样使用mnist数据集来进行分类神经网络的搭建&#xff08;有关mni…

【NI-DAQmx入门】NI-DAQmx之Python

NI-DAQmx Python GitHub资源&#xff1a; NI-DAQmx Python 文档说明&#xff1a;NI-DAQmx Python Documentation — NI-DAQmx Python API 0.9 documentation nidaqmx支持 CPython 3.7和 PyPy3&#xff0c;需要注意的是多支持USB DAQ和PCI DAQ&#xff0c;cDAQ需要指定…

改进的yolov5

The networkstructure of these models is constant, but the modules and con-volution kernels are scaled, which alters the complexity and sizeof each model.&#xff08;这些模型的网络结构是恒定的&#xff0c;但模块和卷积核被缩放&#xff0c;这改变了每个模型的复杂…

自动驾驶算法(五):基于遗传算法的路径规划(上)

目录 1 遗传算法介绍 2 遗传算法代码详解--绘制地图与种群初始化代码讲解 1 遗传算法介绍 模拟生物进化过程&#xff0c;物竞天择&#xff0c;适者生存。 我们先为栅格地图进行编码&#xff1a;从起点0出发到终点24这个栅格。我们首先有一条路径&#xff08;0&#xff0c;6&a…

最近面了12个人,发现连这种基础题都答不上来.....

一般面试我都会问一两道很基础的题目&#xff0c;来考察候选人的“地基”是否扎实&#xff0c;有些是操作系统层面的&#xff0c;有些是 python语言方面的&#xff0c;还有些… 深耕IT行业多年&#xff0c;我们发现&#xff0c;对于一个程序员而言&#xff0c;能去到一线互联网…

golang工程中间件——redis常用结构及应用(string, hash, list)

Redis 命令中心 【golang工程中间件——redisxxxxx】这些篇文章专门以应用为主&#xff0c;原理性的后续博主复习到的时候再详细阐述 string结构以及应用 字符数组&#xff0c;redis字符串是二进制安全字符串&#xff0c;可以存储图片等二进制数据&#xff0c;同时也可以存…

ns3入门基础教程

ns3入门基础教程 文章目录 ns3入门基础教程ns环境配置测试ns3环境ns3简单案例 ns环境配置 官方网站&#xff1a;https://www.nsnam.org/releases/ 代码仓库&#xff1a;https://gitlab.com/nsnam/ns-3-dev 如果安装遇到问题&#xff0c;可以参考以下博文&#xff1a; https://…