C++学习之map和set

目录

一,什么是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.hqwc.cn/news/162323.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring Security入门教程,springboot整合Spring Security

Spring Security是Spring官方推荐的认证、授权框架&#xff0c;功能相比Apache Shiro功能更丰富也更强大&#xff0c;但是使用起来更麻烦。 如果使用过Apache Shiro&#xff0c;学习Spring Security会比较简单一点&#xff0c;两种框架有很多相似的地方。 目录 一、准备工作 …

有没有好用的人事管理系统?什么才是好的人事系统?

人事管理关系到企业各部门的正常运转&#xff0c;一个好的人事管理系统对于公司来说无疑是锦上添花&#xff0c;实现人事个性化管理&#xff0c;可以极大地提高人员管理的效率。但在信息化转型的浪潮下&#xff0c;很多企业人事信息化却遇到不少问题。 那么请花5分钟认真看这篇…

力扣 141.环形链表和142.环形链表2

目录 1.环形链表Ⅰ解题思路2.环形链表Ⅰ代码实现3.环形链表Ⅱ解题思路4.环形链表Ⅱ代码实现 1.环形链表Ⅰ解题思路 利用快慢指针&#xff0c;快指针一次走两个&#xff0c;慢指针一次走一个&#xff0c;如果出现了快指针为空或者快指针的next为空的现象则说明不带环&#xff0…

海康Visionmaster-全局脚本:方案加载完成信号发给通 信设备的方法

需要在方案加载完成后&#xff0c;发送加载完成信号到全局变量&#xff0c;发送给通信设备。 全局脚本的使用可以通过打开示例&#xff0c;完成常用的基本功能开发。 打开全局通信代码后&#xff0c;在脚本中添加代码

Netty入门指南之传统通信的问题

作者简介&#xff1a;☕️大家好&#xff0c;我是Aomsir&#xff0c;一个爱折腾的开发者&#xff01; 个人主页&#xff1a;Aomsir_Spring5应用专栏,Netty应用专栏,RPC应用专栏-CSDN博客 当前专栏&#xff1a;Netty应用专栏_Aomsir的博客-CSDN博客 文章目录 参考文献前言多线程…

【Mybatis小白从0到90%精讲】01:IDEA创建Maven项目,添加Mybatis依赖

文章目录 前言一、IDEA创建Maven项目二、添加依赖前言 Mybatis开发,我们从创建一个Maven项目项目开始,推荐使用的开发工具是IDEA,接下来演示使用IDEA创建Maven项目,并添加Mybatis依赖,每一步对应都有配图,Let’s Go~ 一、IDEA创建Maven项目 打开IDEA,点击左上角菜单:F…

基于Java+SpringBoot+Mybaties-plus+Vue+ElementUI 失物招领小程序 设计与实现

一.项目介绍 失物招领小程序 用户登录、忘记密码、退出系统 发布失物 和 发布招领 查看我发布的失物和招领信息 失捡物品模块可以查看和搜索所有用户发布的信息。 二.环境需要 1.运行环境&#xff1a;java jdk1.8 2.ide环境&#xff1a;IDEA、Eclipse、Myeclipse都可以&#…

春招秋招,遇到在线性格测评要不要真实做?

找工作是一个不衰的话题&#xff0c;不仅仅是大学毕业生们&#xff0c;职场人都绕不过去的话题。如今越来越的企业采用在线测评&#xff0c;很多盆友都遇到了&#xff0c;测评挂了不明觉厉...纷纷发提问救助&#xff0c;怎么才能过测评&#xff1f; 先说原因 求职的人多了&am…

Sam Altman再出手,投资了两个不到20岁的RPA创业者

“AI到底是变革还是泡沫&#xff1f;” 作者 | 王王 首图来源&#xff1a;IndiaTimes Sam Altman又出手了。这次他投资了一个只有5个人的RPA早期团队Induced AI&#xff0c;两位联合创始人Aryan Sharma和Ayush Pathak&#xff0c;一个18岁&#xff0c;一个19岁。 不只是Sam A…

[架构之路-254/创业之路-85]:目标系统 - 横向管理 - 源头:信息系统战略规划的常用方法论,为软件工程的实施指明方向!!!

目录 总论&#xff1a; 一、数据处理阶段的方法论 1.1 企业信息系统规划法BSP 1.1.1 概述 1.1.2 原则 1.2 关键成功因素法CSF 1.2.1 概述 1.2.2 常见的企业成功的关键因素 1.3 战略集合转化法SST&#xff1a;把战略目标转化成信息的集合 二、管理信息系统阶段的方法论…

Redis高级数据类型-HyperLogLogBitmap以及使用两种数据类型完成网站数据统计

网站数据统计 定义相关的Redis Key /*** 单日UV*/public static String getUVKey(String date) {return PREFIX_UVSPLITdate;}/*** 记录区间UV* param startData 开始日期* param endDate 结束日期* return*/public static String getUVkey(String startData,String endDate){r…

Git同时配置Gitee和GitHub

Git同时配置Gitee和GitHub 一、删除原先ssh密钥二、生成密钥 这里的同时配置是针对于之前配置过单个gitee或者github而言的&#xff0c;如果需要看git从安装开始的配置&#xff0c;则可以看这一篇文章 git安装配置教程 一、删除原先ssh密钥 在C盘下用户/用户名/.ssh文件下找到…