C++:set、map的使用及其特性和区别

C++轮子(3) · STL关联容器 我们知道 Concept 表示的不是一个类型而是一个类型集合,所以 Refinement 表示的其实也是一个类型集合,这些类型比 Concept 中的定义的类型要有更多的约束和特性(约束和特性其实是一个问题的两个方面,你约束的越是严格,你能够使用的特性越多,但是你能使用的场景越少,比如 Java 中 Object 类哪儿都能用,又哪儿都用不了)。如果你在你的程序中需要查找最吻合的某个值(比如上面例子中的找到给定分辨率最合适的比特率),你可以使用上面提到的这几个函数,它们可以在logn之内找到给定的位置。 阅读详情
AI摘要

本文深入解析STL中的set、map、multiset和multimap容器的使用方法、特性和区别。介绍了这些容器的数据结构、插入、查找、删除、交换和清空等操作,以及如何遍历容器。特别强调了set和map的底层实现为红黑树,对比了两者在键值存储和查询上的差异。

set、map的使用及其特性和区别

STL总共实现了两种不同结构的管理式容器:树型结构与哈希结构。树型结构的关联式容器主要有四种:set,map,multiset,multimap。下面介绍一下这四种容器的简单使用。

1.set

set里面每个元素只存有一个key值,它支持高效的关键字查询操作,比如检查一个关键字是否在set中。如果这个key值之前存在的话就不插入。

简单使用如下:

插入:

set<int> s;
	s.insert(2);
	s.insert(1);
	s.insert(4);
	s.insert(5);
	s.insert(3);
	s.insert(5);
	s.insert(5);
	s.insert(5);
	s.insert(5);
	s.insert(5);
	for (auto e : s)
	{
		cout << e << " ";
	}
	cout << endl;

插入如上数据之后,打印出来的值为1 2 3 4 5。set容器自动对以上数据进行了排序,并且实现了去重。但是不能对set里的值进行修改。

查找:

//时间复杂度:O(logN)----底层是搜索树
set<int>::iterator pos = s.find(3);
//时间复杂度:O(N)----需要遍历一遍(不建议使用)
//set<int>::iterator pos = find(s.begin(), s.end(), 3);
if (pos != s.end())
{
	cout << "找到了" << endl;
}

set容器中的find查找效率高,因为底层是一个二叉搜索树,比要查找的值小就去左子树查找,反之则去右子树查找。

删除:

//s.erase(3);
s.erase(pos);//找到了我就删,没找到要删的话会报错
for (auto e : s)
{
	cout << e << " ";
}
cout << endl;

采用s.erase(3);这种操作如果没有3并不会报错,如果有3则会删除这个结点。
找到pos位置,采用s.erase(pos);这种操作如果没有3则会报错,如果有3则会删除这个结点。

交换:

set<int> ss;
ss.insert(6);
ss.insert(9);
ss.insert(8);
ss.insert(7);
ss.insert(10);

ss.swap(s);//交换根节点的指针,效率高
for (auto e : s)
{
	cout << e << " ";
}
cout << endl;

两个set的交换的其实是交换结点的指针,效率高。

清空:

s.clear();//清掉所有数据
for (auto e : s)
{
	cout << e << " ";
}
cout << endl;

遍历方法:

//新式for循环
for (auto e : s)
{
	cout << e << " ";
}
cout << endl;

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

推荐大家使用新式for循环~比较简单一些٩(๑❛ᴗ❛๑)۶

2. multiset

其实整体的接口和set都相同,但是multiset可以插入key相同的值。

multiset<int> ms;
ms.insert(2);
ms.insert(1);
ms.insert(4);
ms.insert(5);
ms.insert(3);
ms.insert(5);
ms.insert(5);
ms.insert(5);
ms.insert(5);
ms.insert(5);

for (auto e : ms)//可以重复插入相同key值
{
	cout << e << " ";
}
cout << endl;

auto pos = ms.find(5);
if (pos != ms.end())
{
	cout << "找到了" << endl;//找到的是中序的第一个5
	while (*pos == 5)//往后继续找可以找到后面所有的5
	{
		cout << *pos << endl;
		++pos;
		if (pos == ms.end())//pos指向最后一个的下一个
			break;
	}
}

--pos;//倒数第一个5
ms.erase(pos);

for (auto e : ms)//可以重复插入相同key值
{
	cout << e << " ";
}
cout << endl;

在这里插入图片描述
multiset允许key的冗余,如果用find查找key值时,找到的是中序遍历第一个,因此不断遍历下午可以找到这个multiset里所有的key值。

multiset和set一样不能够对数据进行修改。

3.map

有别于set的是,map是一种key(键),value(值)的形式,用来保存键和值组成的集合,键必须是唯一的,但值可以不唯一。里面的元素可以根据键进行自动排序,由于map是key_value的形式,所以map里的所有元素都是pair类型。pair里面的first被称为key(键),second被称为value(值)。

它可以通过关键字查找映射关联信息value,同时根据key值进行排序。

相关类型的返回值

成员类型含义
key_typeThe first template parameter (Key)
mapped_typeThe second template parameter (T)
value_typepair<const key_type,mapped_type>
简单的使用如下:

插入:

map<string, string> dict;
dict.insert(pair<string, string>("string", "字符串"));//模板类型pair:构造了一个匿名对象插入到map
dict.insert(make_pair("apple", "苹果"));//模板函数make_pair:偷懒了,实际调的是pair
dict.insert({ "left", "左边" });
dict.insert({ "left", "剩余" });//插入不进去了,因为key值已经有了

插入有三种方法:

  1. 采用创建pair的形式插入pair<string, string>("string", "字符串")
  2. 采用make_pair的形式进行插入make_pair("apple", "苹果")
  3. 采用大括号的形式进行插入{ "left", "左边" }

遍历方法:

//新式for循环
for (const auto &e : dict)
{
	cout << e.first << ":" << e.second << endl;
}
cout << endl;

//迭代器遍历
map<string, string>::iterator mit = dict.begin();
while (mit != dict.end())
{
	cout << mit->first << ":" << mit->second << endl;
	cout << (*mit).first << ":" << (*mit).second << endl;
	mit++;
}

打印出来为:(根据key值进行了排序和key值的去重)
在这里插入图片描述

operator[ ]:

operator[]可以通过key值找到对应的value值。并且还可以使用operator[]插入数据。

dict["banana"];

如上,插入一个pair,这个pair的key值为“banana”,value为空字符串(\0)

dict["key"] = "关键字";

如上,插入一个pair,这个pair的key值为“key”,value为“关键字”

dict["left"] = "剩余";

如上,因为本来map里“left”这个key值,所以operator[]找到了这个key值,将它的value改成“剩余”。

打印出来为:
在这里插入图片描述

4.multimap

multimap允许key值的冗余,因此key值相同也可以进行插入。

multimap<string, string> mmp;
mmp.insert(pair<string, string>("left", "左边"));
mmp.insert(make_pair("key","关键字"));
mmp.insert({ "map", "地图" });
mmp.insert({ "left", "剩余" });

for (const auto &e : mmp)
{
	cout << e.first << ":" << e.second << endl;
}

打印出来为:
在这里插入图片描述

set和map特性和区别

set是一种关联式容器,其特性如下:

  1. set以RBTree作为底层容器
  2. 所得元素的只有key没有value,value就是key
  3. 不允许出现键值重复
  4. 所有的元素都会被自动排序
  5. 不能通过迭代器来改变set的值,因为set的值就是键

map和set一样是关联式容器,它们的底层容器都是红黑树,区别就在于map的值不作为键,键和值是分开的。它的特性如下:

  1. map以RBTree作为底层容器
  2. 所有元素都是键+值存在
  3. 不允许键重复
  4. 所有元素是通过键进行自动排序的
  5. map的键是不能修改的,但是其键对应的值是可以修改的
瑞萨MCU定时器API实战:从Smart Configurator配置到中断与输入捕获应用 在嵌入式系统开发中,定时器(Timer)是实现精准时序控制、PWM输出和信号测量的核心硬件外设。其工作原理基于计数器在稳定时钟源驱动下递增或递减,达到预设值后触发中断或改变输出电平,从而为系统提供节拍和事件基准。通过图形化配置工具(如瑞萨的Smart Configurator),开发者可以高效地将复杂的硬件寄存器操作转化为清晰、标准化的C语言API函数,这极大地提升了开发效率并降低了出错风险。这种从硬件抽象到软件接口的技术价值在于,它使得开发者能更专注于应用逻辑,而非底层细节,尤其适用于工业控制、汽车电子等 阅读详情

相关推荐

使用【阿里云百炼】搭建自己的大模型

本文介绍阿里云百炼大模型平台,其为企业级服务平台,融合通义千问等模型,支持多模态能力,提供一站式工具降低开发门槛。重点讲解智能体应用及大模型搭建步骤,含进入创新应用界面、选模型配参数、输指令、导数据、加载知识库、获取API Key、加样例库、配置MCP,还提及模型调试与多平台发布,并附试用链接,助力企业与开发者快速搭建适配业务的AI模型。

Larry的博客 4738

C++中的map和set

本文主要介绍set和map的用法和底层逻辑,以及区别。同时也涉及到哈希表,红黑树等相关知识,但本篇不予介绍。

weixin_61360713的博客 2178

【SigmaStar SSC335系列】空片用Flash_Tool烧写

简介 本文主要讲新拿到的PCBA,板上spi nand flash还是空的,如何在这种情况下烧录固件,这里讲解用官方Flash_Tool烧写的方式。 但只讲一些注意的地方和坑,其它的官方文档里说的比较清楚,不多说。 准备 Flash_Tool烧写软件 编译打包好烧写镜像 串口烧录小板 ----- 这个是个坑,在官方文档里并没有提及,刚开始用的平时调试的USB转串口,怎么都没反应,一度不知烧写软件不对还是硬件有问题,最后通过厂家技术支持才得知,除了专门的Flash_Tool外,还要专门的串口烧录器

老K 4699

C++中map和set的区别

1. 存储方式不同:map以key-value键值对的形式存储元素,而set只存储key关键字。 2. 元素的唯一性不同:map中的键必须唯一,而set中的关键字也必须唯一。 3. 访问元素的方式不同:map可以通过键访问对应的值,而set只能访问key关键字本身。4. 内部实现不同:map通常使用红黑树实现,而set也通常使用红黑树实现,但也可以使用哈希表实现。 因此,在选择使用map还是set时,需要根据具体需求来决定。如果需要存储键值对,并且需要能够通过键访问对应的值,则应该使用map。

Dzh的博客 1107

为什么你的SiC MOSFET仿真不准?可能是离子注入的‘沟道效应’在捣鬼(Silvaco BCA模块详解)

本文深入分析了SiC MOSFET仿真中离子注入沟道效应的关键影响,揭示了Silvaco BCA模块在模拟SiC晶向和角度参数时的核心设置要点。通过详细解析晶圆偏切与注入角度的等效关系,提供优化MOSFET沟道区注入仿真的五步实战方法,帮助工程师将阈值电压仿真误差从26%降低到5%以内。

weixin_26789847的博客 410

系统磁盘从MBR格式转换成GPT格式来升级win11

之前的《》中说到,需要把磁盘格式转化为MBR格式才能执行下去。问题是,win10升级win11要求启动方式为UEFI的话,磁盘格式不能为MBR。其实不升级也不影响啥,但是就是想好看点。所以花了点时间折腾了一下。我这是双系统,所以直接去A系统修复B系统的磁盘格式和引导。

qq_42520962的博客 9041

C++ STL中,map和set有什么区别,分别又是怎么实现的?

map和set都是C++的关联容器,其底层实现都是红黑树(RB-Tree)。由于 map 和set所开放的各种操作接口,RB-tree 也都提供了,所以几乎所有的 map 和set的操作行为,都只是转调 RB-tree 的操作行为。 map和set区别在于: (1)map中的元素是key-value(关键字—值)对:关键字起到索引的作用,值则表示与索引相关联的数据;Set与之相对就是关键字的简单集...

学无止尽,谨言慎行! 6637

【专栏必读】王道考研408计算机组成原理万字笔记使用说明及章节导航

本文是为准备408王道计算机组成原理考试的学生精心整理的万字笔记,涵盖了从计算机系统概述、数据表示和运算到存储系统、指令系统等多个章节的重点内容。本文强调了学习笔记的重要性,并分享了学习建议,如按视频课逻辑记录,建立学科框架。笔记详细记录了每章的关键知识点,包括存储器、CPU、I/O系统的工作原理,还附带了习题和思维导图,旨在帮助考生高效复习。

快乐江湖的博客 9万+

C++ STL中 set 和 map 的区别

set和map是C++ STL中两种重要的关联容器,它们各自有不同的特点和适用场景。set主要用于存储唯一且排序的元素,而map则用于存储键值对,并根据键进行排序。尽管它们在底层实现上有许多相似之处,但在接口和使用上却有明显的区别。通过理解这些区别,我们可以更好地选择和使用它们,以满足不同的编程需求。

红军不怕远征难,万水千山只等闲 2518

AttributeError: module ‘numpy‘ has no attribute ‘int‘解决方案

本文主要介绍了AttributeError: module ‘numpy’ has no attribute 'int’解决方案,希望能对使用numpy的同学们有所帮助。 文章目录 1. 问题描述 2. 解决方案 2.1 方案一 2.2 方案二

weixin_43178406的博客 28万+

手把手教您解决 AdGuard Home DNS重写功能失效的问题

AdGuard Home 设置了 DNS 重写,规则明明没问题,客户端却死活解析不到内网 IP?🤯 别急着重装!🚫 本文手把手教你如何解决软路由 DNS 解析“玄学”故障!🛠️🚀

XiaoqiangClub的博客 920

C++进阶之map与set

stl中将数据结构叫做容器。 容器分为 序列式容器:vector/list... 就类似线性表 关联史容器:map/set.. 数据之间有强烈的关联性,底层是搜索树 栈和队列是适配器 set底层就是搜索树。 void test_set1() { //排序+去重 set<int> s; s.insert(3); s.insert(1); s.insert(8); s.insert(2); s.insert(5); s.insert(5); s.insert(5)

cls的博客 3076

LPDDR5 学习笔记05:WCK操作详解

LPDDR5 SDRAM采用双时钟设计,写时钟(WCK)频率为命令时钟(CK)的2倍或4倍,需要通过WCK2CK同步机制解决时钟域对齐问题。该同步操作由带特殊标志位的CAS命令触发,控制器需提供半频WCK脉冲进行状态校准。同步完成后才能执行读写操作,且支持多存储体组同步和WCK常开模式以优化性能。掉电后必须重新执行同步流程,确保时钟域正确对齐。该机制有效解决了高速内存接口的时序挑战,为LPDDR5性能提升提供关键技术支撑。

一只豌豆象的博客 2006

STL(四) map,set,deque

STL(四)    map,set,deque 8. 双端队列deque     1)底层结构:段落连续空间(每一段都是一个vector,不同vector之间像list一样连接起来)。     2)三种容器对比:         1. vector随机访问效率高,插入删除效率低。         2. list随机访问效率低,插入删除效率高(头尾添加)。         3. dequ...

zz_dude的博客 167

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

【C++】【总结】unordered_map,unordered_set,map和set的用法和区别

unordered_map 头文件:#include 介绍:std::unordered_map 本来就是以key来查找value而设计。 方法: Insert

zjajgyy的博客 4万+

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

【C++】C++ STL 树形结构容器全解析:map、set、multimap、multiset 的使用与区别

大家好,我是店小二!今天为大家带来 C++ STL 树形结构容器全解析:map、set、multimap、multiset 的使用与区别。本次分享主要聚焦于这几种容器的使用方法,帮助大家了解它们的基本功能和常用接口。需要提前说明的是,今天的内容偏重实用性,旨在让大家快速上手,没有深入探讨底层原理。希望能对大家有所帮助!

专注于 C/C++ 后端开发,涵盖基础语法、Linux系统与网络、MySQL数据库、常见算法及项目经验。 2975

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

【C++】set和map的使用

对于STL容器来说,有很多相似的功能,所以这里主要将与之前不同的功能说清楚。

qq_62939852的博客 2282

全面解析 C++ STL 中的 set 和 map

基于哈希表实现,提供常数时间复杂度 O(1)O(1)O(1) 的查找和插入操作。是最常用的两类关联容器。希望通过本文的学习,你能够深入掌握这些强大的容器,提升 C++ 编程技能。红黑树的特点确保了查找、插入和删除操作的时间复杂度都为 O(log⁡N)O(\log N)O(logN)。C++ 标准模板库(STL)中的关联式容器以其强大的功能和高效性成为开发者解决复杂数据组织问题的重要工具。在某些场景下非常有用,例如存储学生成绩时,可能有多个学生取得相同的分数。的扩展,允许相同的键有多个值(即支持键的冗余)。

2406_83947720的博客 3748

【C++】map和set的使用

set 的声明如下,其中T代表 set 底层存储的关键字类型。set 默认要求类型T支持小于()比较操作。若T不支持该操作,或需要自定义比较规则,可自行实现仿函数,并将其作为第二个模板参数传入。set 底层存储数据的内存,默认通过 STL 提供的空间配置器申请。若有特殊需求,也可自行实现内存池,将其作为第三个模板参数传入。一般情况下,无需手动指定后两个模板参数,使用 set 的默认配置即可满足需求。set 底层基于红黑树实现,其增、删、查操作的时间复杂度均为O(logN)。

zzzsde的博客 873

C++:map和set

set 是一个K模型的搜索二叉树 #includemap是KV模型的搜索二叉树,insert和[]用法是重点,其他用法参考set用来表示具有一一对应关系的一种结构,该结构中一般只包含两个成员变量key和value,key代表键值,value表示与key对应的信息。比如:现在要建立一个英汉互译的字典,那该字典中必然有英文单词与其对应的中文含义,而且,英文单词与其中文含义是一一对应的关系,即通过该应该单词,在词典中就可以找到与其对应的中文含义。............

zhang_si_hang的博客 4672

C++ map和set使用

map:一种键值对(Key-Value) 集合,键(Key)唯一且可对应任意类型的值(Value),好比带标签的收纳盒,每个标签(Key)只能对应一个盒子(Value),通过标签能快速找到盒子。set:一种无重复元素的集合,只存储单个值(Value)且值不重复,类似去重后的清单,比如记录已打卡的景点,不会出现同一个景点被重复记录的情况。

2401_88966792的博客 1189

C++中map和set的使用与区别

set set是一种关联式容器,其特性如下: set以RBTree作为底层容器所得元素的只有key没有value,value就是key不允许出现键值重复所有的元素都会被自动排序不能通过迭代器来改变set的值,因为set的值就是键 针对这五点来说,前四点都不用再多作说明,第五点需要做一下说明。如果set中允许修改键值的话,那么首先需要删除该键,然后调节平衡,在插入修改后的键值,再调节平

zy20150613的博客 2万+

【C++】set和map

map与·set

喜欢编写一些小程序的科班菜鸟,但是由于准备考研,博客不能及时更新了,不好意思! 1756

【C++】map和set

详细讲解C++,map和set,包括:一,二叉搜索树 1 基本介绍 2 性能分析 3 查找,插入,删除操作 4 ⼆叉搜索树key和key/value 二,set lower_bound equal_range 使用 三,map 1 基本介绍 2 使用示例 2.1 初始化map 2.2 [ ] multimap

tan_run的博客 1647
上一篇: Linux:简单的vim配置文件(适合萌新使用~)
下一篇: C++:map的operator[]的底层实现及其使用
ETalien_
博客等级 码龄8年 154粉丝 199原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值