set、map使用及其细节

news2025/2/5 6:06:26

🧸🧸🧸各位大佬大家好,我是猪皮兄弟🧸🧸🧸
在这里插入图片描述

文章目录

  • 一、两个概念
    • ①关联式容器与序列式容器
    • ②键值对
  • 二、set、map
    • ①set
      • set的两种遍历方式
      • set的升降序排序
      • set的erase
      • set的count
    • ②map
      • SGI-STL中键值对的定义
      • map的insert
      • 打印map中的元素
      • 经典Key/Value模型,水果数数
      • map的operator[]
      • map的at
      • map的operator[]底层简单分析

一、两个概念

①关联式容器与序列式容器

序列式容器也就是vector,list,deque,forword_list等等这种,因为其底层为线性序列的数据结构,里面存的是元素本身
关联式容器:关联式容器也是用来存储数据的,与序列式容器不同的是,其里面存的是<Key,Value>结构的键值对,在数据检索时比序列式容器效率更高

②键值对

用来表示具有一一对应关系的一种结构,该结构中一般只包含两个成员变量Key和Value,Key代表值,Value表示与Key对应的信息,比如:现在要建立一个英汉翻译的字典,Key存英文,用于检索它的中文Value

二、set、map

①set

set的本质就是一个Key的模型,用于确认在与不在,几乎所有函数的返回值都是bool
在这里插入图片描述
Key模型是不允许修改的,因为也没办法修改,不同的Key对应的是不同的东西,所以说set只能删除掉,再重新添加。

set的两种遍历方式

set和map的遍历都是通过迭代器,迭代器也是一种设计模式,访问容器,并没有暴露容器的底层结构,不关心底层细节,以统一的方式去进行访问,所以迭代器也是STL六大组件之一。

int a[] = {1,2,1,6,3,8,5};
set<int>s(a,a+sizeof(a)/sizeof(int));
//set<int>s{1,2,1,6,3,8,5}列表初始化,initializer_list
//1.while(it!=s.end())
set<int>::iterator it = s.begin();
while(it!=s.end())
{
	...
}
//2.for循环,但是for底层是迭代器,所以严格来说算作一种
for(auto e:s)
{
	...
}

set的升降序排序

因为set是Key的模型,底层是一颗搜索二叉树,所以它对应的搜索二叉树的中序遍历就差异达到排序+去重的效果
在这里插入图片描述
可以看出,默认是升序,那么我们想让他降序就需要传仿函数过去set<int,greater<int>> s;//第三个是空间配置器,这里可以不用管

set的erase

set的erase,因为set底层就是搜索二叉树,所以说白了搜索二叉树的删除就分为三种情况
1.删除结点只有一个孩子并且是根结点,那么根结点转移
2.删除结点只有一个孩子并且不是根,那么父节点领养
3.删除结点有两个孩子:需要使用替换法

搜索二叉树详解

但是set提供的就是:删除迭代器位置,删除值,删除迭代器区间
在这里插入图片描述
所以我们这时可以先去找到要删除的值或者位置–>find,一般来说都会配套使用
在这里插入图片描述

auto pos = s.find(x);
if(pos!=s.end()) s.erase(pos);

这时,又会有迭代器失效的问题,其实不管我们用什么容器,它的迭代器失效还是不失效,我们一律把它当做失效来处理,也就是说每一次的删除我们都要重新的去找,或者说有些容器的erase提供了下一个位置的迭代器,我们用pos来接收一下
在这里插入图片描述

//set:
auto pos = s.find(x);
if(pos!=s.end()) s.erase(pos);
pos = s.find(y);
if(pos!=s.end()) s.erase(pos);
//erase返回迭代器的容器
...
pos = v/*容器名*/.erase(pos);

set的count

set的count我们有时也用来看这个元素在不在set当中,但是count是用来数这个元素一共有几个,set本来就是搜索二叉树不允许键值冗余,那要他来干什么??其实是为了接口的一致性,像用哈希来实现的multiset就会允许键值冗余,会提供count接口

②map

在这里插入图片描述

SGI-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)
	{}	
};

map的insert

在这里插入图片描述
但是呢,map不是插入普通的值,map是Key Value模型,底层是红黑树,需要插入的是pair这个结构体

map<string,string> dict;
//1
pair<string,string>kv1("sort","排序");
dict.insert(kv1);
//2
dict.insert(pair<string,string>("zhupi","小菜鸟"))
//3
typdef pair<string,string> DictKV;
dict.insert(DictKV("left","左"));
//4
//常用的make_pair,需要包含头文件 utility(实用工具)
//也有可能被间接包了,比如map,最好自己包一下
dict.insert(make_pair("string","字符串"));

在这里插入图片描述
make_pair是一个函数模板,优势就在于可以自动推导,因为较短,一般会被定义成内联,在预编译阶段就可替换

打印map中的元素

//错误写法
while(it!=dict.end())
{
	cout<<*it<<" ";
	++it;
}
cout<<endl;

因为map中存的是pair结构体,cout中并没有pair的重载,所以输出错误,从上面的键值对pair的定义中我们可以看出,pair有两个成员,first和second,所以:

cout<<(*it).first<<(*it).second<<endl;

*除此之外,之前在模拟实现的时候,会重载一个operator->,返回的是&(this),迭代器转换为地址,但在使用的时候实际上是it->->但是编译器为了可读性,优化成了->,所以我们还可以这样访问pair中的成员

//map的迭代器很喜欢用->
cout<<it->first<<it->second<<endl;
for(const auto & kv:dict)
{
	cout<<kv.first<<":"<<kv.second<<endl;
}

经典Key/Value模型,水果数数

string arr[] = {"苹果","西瓜","苹果 ","西瓜","苹果","苹果","西瓜","苹果","香蕉","苹果","香蕉"};
map<string,int> countMap;
for(auto &str:arr)
{
	auto it = count.find(str);
	if(it!=countMap.end())
	{
		it->second++;
	}
	else
	{
		countMap.insert(make_pair(str,1));
		//make_pair自动推导
	}
	auto it = countMap.begin();
	while(it!=countMap.end())
	{
		cout<<it->first<<":"<<it->second<<endl;
		it++;
	}
}

map的operator[]

可以看出,上面这样操作很麻烦,map中还提供了更方便的方式去修改value,那就是operator[]

它并不是像数组那样的下标随机访问,map这样的树形结构,[]可以很容易的想到并不是下标
在这里插入图片描述
map的作用是,给一个key,返回value的引用

作用:
①map中有这个key,返回value的引用
②map中没有这个key,会插入一个pair(key,V());因为这个value有可能是string或者说更复杂的自定义类型,需要调用构造函数来进行初始化

这样一来,水果数数就变得很方便

for(auto &str:arr)
{
	countMap[str]++;
}

map的at

说到了operator[],那么就很容易联想到一起的at
at与operator[]来说就少了一个功能,at只能查找+修改,在就返回Value的引用,不在就抛异常

map的operator[]底层简单分析

先来看看insert的细节
在这里插入图片描述
insert返回的是一个pair<iterator,bool>
①没有该Key,就插入,并且返回哪个位置的迭代器,把second设为true
②有该Key,返回迭代器,把second设为false
第二个参数就代表插入是否成功

那么这下我们就可以很容易的写出map的operator[]了
在这里插入图片描述

V& operator[](const K&key)
{
	pair<iterator,bool> ret = insert(make_pair(key,V()));
	return ret.first->second;
}
//通过拿到迭代器,再用operator->->拿到second也就是value返回即可

在这里插入图片描述

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

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

相关文章

ISCSLP论文介绍|利用BERT提高语种识别性能

本文介绍清华大学语音与音频技术实验室&#xff08;SATLab&#xff09;ISCSLP 2022录用论文。BERT-LID: Leveraging BERT to Improve Spoken Language Identification。这篇文章将BERT模型引入到语种识别领域。利用BERT模型的优越性&#xff0c;再结合下游不同的神经网络模型&a…

OFDM系统中基于dmrs导频的时间跟踪、频率跟踪算法

目录发射端模型假设接收端模型假设时延估计&#xff08;时间跟踪&#xff09;频偏估计&#xff08;频率跟踪&#xff09;在OFDM系统中&#xff0c;为了估计出信号传输遇到的时间偏移和频率偏移&#xff0c;可以采用导频进行估计。 发射端模型假设 我们假设如下模型&#xff1…

如何熟练掌握运用Delft3D建模、水动力模拟方法及在地表水环境影响评价中的实践技术

Delft3D是由荷兰Delft大学WL Delft Hydraulics开发的一套功能强大的软件包&#xff0c;主要应用于自由地表水环境。该软件具有灵活的框架&#xff0c;能够模拟二维和三维的水流、波浪、水质、生态、泥沙输移及床底地貌&#xff0c;以及各个过程之间的相互作用。它是国际上最为先…

使用 C# Graphics 绘图来绘制一个足球

背景 2022卡塔尔世界杯是足球爱好者的狂欢&#xff0c;这与我毫无关系&#xff0c;作为一个缺乏运动的人&#xff0c;还是不要去看人家玩命的运动了。虽然不看球&#xff0c;不过这波热度的持续冲击&#xff0c;还是让我在朋友圈刷到了结局 ———— 球王梅西如愿以偿捧得金杯…

Bootstrap5 下拉菜单

下拉菜单可以是单选下拉菜单&#xff0c;也可以是多选的下拉菜单。 单选下拉菜单&#xff1a; 多选下拉菜单&#xff1a; 在 Bootstrap5 中下拉菜单 <select> 元素可以使用 .form-select 类来渲染 : 实例 <select class"form-select"> <option>…

内核启动过程分析

目录 一、内核源码获取查看 1.1、Source Insight使用 二、查看链接脚本 三、分析head.S 3.1、到入口前代码 3.2、内核启动的汇编阶段 四、main.c内核启动的c语言阶段 4.1、内核打印函数printk 4.2、启动信息 五、rest_init函数 5.1、进程0、进程1、进程2​编辑 5.2、…

详细复习云开发~小程序【搜索功能、登陆注册功能、点赞收藏评论功能、评论功能、CMS网页版管理后台】

文章目录一&#xff0c;搜索功能1-1&#xff0c;需求1-2&#xff0c;实现原理1-3&#xff0c;模糊搜索的代码实现1-3-1&#xff0c;模糊搜索单个字段1-3-2&#xff0c;模糊搜索多个字段&#xff08;满足一个即可&#xff09;1-3-3&#xff0c;模糊搜索多个字段&#xff08;要同…

python获取redis memory使用情况

项目研发过程中&#xff0c;用到Python操作Redis场景&#xff0c;记录学习过程中的心得体会。 一、环境搭建 Windows Anaconda3安装redis第3方包&#xff0c;pip install -u redis pip install -u # 升级安装 linux下查看redis配置信息bind 127.0.0.1 # 表示只允许本地访问,…

AssetBundle依赖打包有哪些注意点

1&#xff09;AssetBundle依赖打包有哪些注意点 ​2&#xff09;子程序集如何引用Assembly-CSharp.dll 3&#xff09;Unity的线性空间下自定义贴图在PS中修改问题 4&#xff09;如何关闭视锥体剔除 这是第318篇UWA技术知识分享的推送。今天我们继续为大家精选了若干和开发、优化…

CSS3之2D转换

文章目录2D转换一、transform1-1.2D转换之移动translate1-2.translate&#xff08;百分比&#xff09;盒子居中二、rotate2-1.旋转效果2-2.transform-origin设置旋转中心点三、2D转换之缩放scale四、2D转换综合写法总结2D转换 转换&#xff08;trabsform&#xff09;是CSS3中具…

SPDK块设备bdev简介

介绍 SPDK Bdev架构 SPDK块设备层&#xff08;通常简称为bdev&#xff09;是一个C库&#xff0c;旨在等同于操作系统块存储层&#xff0c;该层通常位于传统内核存储堆栈中设备驱动程序的正上方。具体来说&#xff0c;此库提供以下功能&#xff1a; 一种可插拔模块API&#xf…

Effective C++(二):构造/析构/赋值运算

个人读书记录&#xff0c;不适用教学内容。 目录 条款05&#xff1a;了解C默默编写并调用了哪些函数 条款06&#xff1a;若不想使用编译器自动生成的函数&#xff0c;就该明确拒绝 条款07&#xff1a;为多态基类声明virtual析构函数 条款08&#xff1a;别让异常逃离析构函数…

设备巡检系统哪个软件好?

本文将介绍&#xff1a;1、好用的设备巡检系统&#xff0c;2、评价设备巡检系统好用的标准&#xff1b;3、做好设备管理的几大关键 现今许多企业&#xff0c;尤其是制造业&#xff0c;规模日趋机械化、自动化、大型化、高速化和复杂化&#xff0c;对设备巡检工作的要求越加精细…

微信小程序网络请求

小程序的网络请求的文档是很少的&#xff0c;只提供了API&#xff0c;例子也不举。 基本使用 最简单的使用如下&#xff1a; 就是调用wx.request方法&#xff0c;这个方法已经能够应付大部分的网络请求了。 onLoad() {wx.request({url: http://123.207.32.32:1888/api/city/a…

我学python的那段日子(五)python中的函数

python中的函数 1.1自定义函数 1.1.1 函数的定义 ​ 和Java一样&#xff0c;python也有内置函数和自定义函数&#xff0c;内置函数是python已经定义好的函数&#xff0c;而自定义函数则是我们根据需要自己定义的函数。 ​ 语法 def 函数名称(参数): ​ 函数体 ​ 其中参数的…

一个转行学习前端的初学者,应该如何计划自己的学习规划?

就目前的发展来看&#xff0c;在语言排行中&#xff0c;前端多年霸主的地位还未被撼动&#xff0c;前端语言的特点就注定了很多公司会选用它&#xff0c;强大的第三方库使前端正在web端的强大无法被替代。目前由于大数据&#xff0c;人工智能的发展&#xff0c;互联网成为了发展…

Bootstrap5 复选框与单选框

如果您希望用户从预设选项列表中选择任意数量的选项&#xff0c;可以使用复选框&#xff1a; 实例 <div class"form-check"> <input class"form-check-input" type"checkbox" id"check1" name"option1" value&quo…

【Python机器学习】朴素贝叶斯分类的讲解及预测决策实战(图文解释 附源码)

需要代码请点赞关注收藏后评论区留言私信~~~ 朴素贝叶斯分类 朴素贝叶斯&#xff08;nave Bayes&#xff09;分类是基于贝叶斯定理与特征条件独立假定的分类方法。 设试验E的样本空间为S&#xff0c;A为E的事件&#xff0c;B_1&#xff0c;B_2&#xff0c;⋯&#xff0c;B_n为…

深入浅出理解Java并发AQS的共享锁模式

自定义共享锁例子 首先我们通过AQS实现一个非常最最最轻量简单的共享锁例子&#xff0c;帮助大家对共享锁有一个整体的感知。 Slf4j public class ShareLock {/*** 共享锁帮助类*/private static class ShareSync extends AbstractQueuedSynchronizer {private int lockCount…

C. Sequence Pair Weight(数学贡献法)

Problem - 1527C - Codeforces 序列的权重被定义为具有相同值&#xff08;aiaj&#xff09;的无序索引对&#xff08;i,j&#xff09;&#xff08;这里i<j&#xff09;的数量。例如&#xff0c;序列a[1,1,2,2,1]的权重是4&#xff0c;具有相同值的无序索引对的集合是&#x…