map set 使用快速上手【C++】

news2024/11/18 9:47:28

目录

一,关联式容器 

二,键值对  

三,set

1)使用参考此文档

2)count 函数

3)multiset类

四,map

1. 模板参数介绍

2.operator[]介绍

3. multimap


 英语比较好的同学可以自行查找文档 学习使用

set - C++ Reference (cplusplus.com)

一,关联式容器 

 在初阶阶段,我们已经接触过STL中的部分容器,比如:vector、list、deque、forward_list(C++11)等,这些容器统称为序列式容器,因为其底层为线性序列的数据结构,里面 存储的是元素本身。那什么是关联式容器?它与序列式容器有什么区别? 关联式容器也是用来存储数据的,与序列式容器不同的是,其里面存储的是<key, value>结构的 键值对,在数据检索时比序列式容器效率更高。

序列容器和关联容器的主要区别在于元素的排列方式访问方式。序列容器按照元素的插入顺序进行排序,可以通过位置(索引)来访问元素;而关联容器按照键的顺序进行排序,可以通过键来访问元素。另外,序列容器支持快速的随机访问,而关联容器则不支持。

二,键值对  

用来表示具有一一对应关系的一种结构,该结构中一般只包含两个成员变量key和value,key代表键值,value表示与key对应的信息
比如:现在要建立一个英汉互译的字典,那该字典中必然有英文单词与其对应的中文含义,而且,英文单词与其中文含义是一一对应的关系,即通过该应该单词,在词典中就可以找到与其对应的中文含义。

像这样:

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

根据应用场景的不桶,STL总共实现了 两种不同结构的管理式容器树型结构与哈希结构树型结构的关联式容器主要有四种:map、set、multimap、multiset。这四种容器的共同点是:使用平衡搜索树(即红黑树)作为其底层结果,容器中的元素是一个有序的序列。下面一依次介绍每一个容器。

三,set

特点: 

1. set是按照一定次序存储元素的容器
2. 在set中,元素的value也标识它(value就是key,类型为T),并且每个value必须是唯一的。
set中的元素不能在容器中修改(元素总是const),但是可以从容器中插入或删除它们。
3. 在内部,set中的元素总是按照其内部比较对象(类型比较)所指示的特定严格弱排序准则进行
排序。
4. set容器通过key访问单个元素的速度通常比unordered_set容器慢,但它们允许根据顺序对
子集进行直接迭代。
5. set在底层是用二叉搜索树(红黑树)实现的。
注意:
1. 与map/multimap不同,map/multimap中存储的是真正的键值对<key, value>,set中只放
value,但在底层实际存放的是由<value, value>构成的键值对。
2. set中插入元素时,只需要插入value即可,不需要构造键值对。
3. set中的元素不可以重复(因此可以使用set进行去重)。
4. 使用set的迭代器遍历set中的元素,可以得到有序序列
5. set中的元素默认按照小于来比较
6. set中查找某个元素,时间复杂度为:$log_2 n$
7. set中的元素不允许修改(为什么?)——保证树结构
8. set中的底层使用二叉搜索树(红黑树)来实现。

1)使用参考此文档

set - C++ Reference (cplusplus.com)

使用比较简单,就只讲解一些特殊的点:

set结构特点:

1. 中序遍历树时呈现有序性。

2. 数据去重性。

2)count 函数

set的count 函数,功能是统计相同key的个数。

功能意义不是很大,因为set类具有去重性,所以就跟find()函数功能重合。

3)multiset类

multiset类与set一个重要区别——multiset类允许重复数据

假设:2 2 3,插入2,2的位置可以是2的左右孩子; 当通过查找时(set一般通过中序查找方法)首先查到的2也就是中序最先遍历到的。

四,map

1. map是关联容器,它按照特定的次序(按照key来比较)存储由键值key和值value组合而成的元素。
2. 在map中,键值key通常用于排序和惟一地标识元素,而值value中存储与此键值key关联的内容。键值key和值value的类型可能不同,并且在map的内部,key与value通过成员类型 value_type绑定在一起,为其取别名称为pair:  typedef pair<const key, T> value_type;
3. 在内部,map中的元素总是按照键值 key进行比较排序的
4. map中通过键值访问单个元素的速度通常比unordered_map容器慢,但map允许根据顺序对元素进行直接迭代(即对map中的元素进行迭代时,可以得到一个有序的序列)。
5. map支持下标访问符,即在[]中放入key,就可以找到与key对应的value。
6. map通常被实现为二叉搜索树(更准确的说:平衡二叉搜索树(红黑树))。

1. 模板参数介绍

key: 键值对中key的类型
T: 键值对中value的类型
Compare: 比较器的类型,map中的元素是按照key来比较的,缺省情况下按照小于来比较,一般情况下(内置类型元素)该参数不需要传递,如果无法比较时(自定义类型),需要用户自己显式传递比较规则(一般情况下按照函数指针或者仿函数来传递)
Alloc:通过空间配置器来申请底层空间,不需要用户传递,除非用户不想使用标准库提供的空间配置器。
简单尝试一下下面代码:
void Test_map()
{
	map<string, string> m1;
	m1.insert(make_pair("string", "字符串")); // 可以写成pair<string, string>("string", "字符串"),创建匿名对象
	m1.insert(make_pair("func", "函数"));
	m1.insert(make_pair("sort", "排序"));
	m1.insert(make_pair("void", "空返回"));

	auto dir = m1.begin();
	while (dir != m1.end())
	{
		cout << (*dir).first << " second:" << (*dir).second << endl;
        // cout<< dir->first ... ,dir是迭代器类型,STL一般是实现了->的重载
		dir++;
	}
	cout << endl;
}

以上代码中使用了make_pair类,那这个make_pair类有什么特点??

本质上就是一个模板函数,里面封装了返回匿名对象,选择使用这么模板函数目的就是省略pair<string, string>类型的填写,类型自动推导。

2.operator[]介绍

可以简单理解为:通过该成员函数,返回键值表中的_val的引用。(不理解也没关系,后面逐步理解) 

我们先尝试写一个记录物品数量的代码
void Test_map_operator()
{
	const char* arr[] = { "瓜", "花","瓜", "梨", "瓜" };

	map<string, int> count;
	for (auto& e : arr)
	{
		auto ret = count.find(e);
		if ( ret == count.end())
		{
			count.insert(make_pair(e, 1));
		}
		else
		{
			ret->second++;
		}
		// count[e]++;
	}
	for (auto& e : count)
	{
		cout << e.first << ":" << e.second << endl;
	}
}

结果是正常的,然后我们将第一个auto的函数内容注释,替代为cout[e]++;  运行。运行结果跟我们的代码结果相同。这就有意思了。

文档中是这样解释这个代码的等效代码:

我们分析一下:
简单来个实验:
void Test_map_insert()
{
	map<string, string> m1;
	m1.insert(make_pair("string", "字符串"));
	m1.insert(make_pair("func", "函数"));
	m1.insert(make_pair("sort", "排序"));
	m1.insert(make_pair("void", "空返回"));

	m1["afeng"];            // 查找,如果没有,则进行创建(修改)
	m1["afeng"] = "阿峰";   // 修改
	cout << m1["afeng"] << endl;
	m1["afeng"] = "阿峰fc"; // 查找 + 修改
	cout << m1["afeng"] << endl;
}

3. multimap

multimap中的接口可以参考map,功能都是类似的。
注意:
1. multimap中的key是可以重复的。
2. multimap中的元素默认将key按照小于来比较
3. multimap中没有重载operator[]操作(同学们可思考下为什么?)。(因为允许键值冗余,所以无法准确查找到对应的键值对)
4. 使用时与map包含的头文件相同

下一期预告:我们从底层了解AVL树,上强度!

结语

   本小节就到这里了,感谢小伙伴的浏览,如果有什么建议,欢迎在评论区评论,如果给小伙伴带来一些收获请留下你的小赞,你的点赞和关注将会成为博主创作的动力

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

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

相关文章

springboot+avue框架开发的医院绩效考核系统全套源码

医院综合绩效核算系统全套源码 &#xff08;应用案例自主版权演示&#xff09; 医院绩效考核系统以医院的发展战略为导向&#xff0c;把科室、员工的绩效考核跟战略发展目标紧密结合&#xff0c;引导医院各个科室、各员工的工作目标跟医院的发展目标结合在一起&#xff0c;实现…

代码随想录Day26 贪心01 LeetCode T53 最大子数组和

LeetCode T53 最大子数组和 题目链接:53. 最大子数组和 - 力扣&#xff08;LeetCode&#xff09; 题目思路: 贪心贪的是哪里呢&#xff1f; 如果 -2 1 在一起&#xff0c;计算起点的时候&#xff0c;一定是从 1 开始计算&#xff0c;因为负数只会拉低总和&#xff0c;这就是贪…

VPN访问外网的原理

一.前言 许多人都用VPN翻墙&#xff0c;那么VPN为什么可以做到访问外网&#xff1f; VPN的全称叫“Virtual Private Network”意思就是虚拟私人专用网络&#xff0c;是专用网络的延伸&#xff0c;通过VPN&#xff0c;可以模拟点对点专用连接的方式&#xff0c;通过共享和公共网…

对知识蒸馏的一些理解

知识蒸馏是一种模型压缩技术&#xff0c;它通过从一个大模型&#xff08;教师模型&#xff09;中传输知识到一个小模型&#xff08;学生模型&#xff09;中来提高学生模型的性能&#xff0c;知识蒸馏也要用到真实的数据集标签。 软损失soft loss就是拿教师模型在蒸馏温度为T的…

Ai写作创作系统ChatGPT网站源码+图文搭建教程+支持GPT4.0+支持ai绘画(Midjourney)/支持OpenAI GPT全模型+国内AI全模型

一、AI创作系统 SparkAi创作系统是基于OpenAI很火的ChatGPT进行开发的Ai智能问答系统AI绘画系统&#xff0c;支持OpenAI GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署…

map 和 set 的一起使用

map 和 set 一起使用的场景其实也蛮多的&#xff0c;最近业务上就遇到了。需求是这样的&#xff0c;一条路径&#xff08;mpls中的lsp&#xff09;会申请多个 id&#xff0c;这个 id 是独一无二的。这里很显然就就一个”一对多“的情况&#xff0c;合适用这个容器不保存这些信息…

【Java集合类面试九】、介绍一下HashMap的扩容机制

文章底部有个人公众号&#xff1a;热爱技术的小郑。主要分享开发知识、学习资料、毕业设计指导等。有兴趣的可以关注一下。为何分享&#xff1f; 踩过的坑没必要让别人在再踩&#xff0c;自己复盘也能加深记忆。利己利人、所谓双赢。 面试官&#xff1a;介绍一下HashMap的扩容机…

【Java集合类面试七】、 JDK7和JDK8中的HashMap有什么区别?

文章底部有个人公众号&#xff1a;热爱技术的小郑。主要分享开发知识、学习资料、毕业设计指导等。有兴趣的可以关注一下。为何分享&#xff1f; 踩过的坑没必要让别人在再踩&#xff0c;自己复盘也能加深记忆。利己利人、所谓双赢。 面试官&#xff1a;JDK7和JDK8中的HashMap有…

【保姆级教程】:docker搭建MongoDB三节点副本集

容器可以理解为一个进程&#xff0c;镜像是把环境&#xff0c;组件等都配置好&#xff0c;运行成容器的&#xff0c;容器里面运行服务&#xff0c;也可以说是一个进程。镜像是模板&#xff0c;镜像是实例。 一个镜像可以创建多个实例。也就是多个容器&#xff0c;容器之间相互…

【已解决】vue项目之爆红红红红······

我是用npm update更新依赖的时候就开始爆红了... 这里显示是依赖问题&#xff0c;有多种解决方式&#xff1a;1&#xff0c;哪个依赖出问题就去提高或者降低依赖的版本&#xff1b;2&#xff0c;提高或者降低vue-cli的版本。 第一种&#xff1a; 我的报错信息提示eslint这个依…

Linux系统开发(1):IO多路复用

IO即输入输出&#xff0c;是主存和外部设备&#xff08;磁盘驱动器、终端和网络&#xff09;之间复制数据的过程。 IO过程 应用程序进程向操作系统发起IO调用请求&#xff1b;操作系统将外部设备的数据加载到内核缓冲区&#xff1b;操作系统将内核缓冲区的数据拷贝到进程缓冲…

Linux:firewalld防火墙-小环境实验(3)

环境介绍 本章为全纯手打&#xff0c;无任何复制&#xff0c;如果哪句命令出错&#xff0c;请评论出来我会快速修改 需求 图中防火墙区域为网关服务器上分区 &#xff0c;在网站服务器上可以使用默认的或者别的 1&#xff09;首先关闭全部的服务器的防火墙&#xff0c;实现全…

【GWO-BP预测】基于灰狼算法优化BP神经网络回归预测研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

YOLOv5项目实战(1)— 如何去训练模型

前言:Hello大家好,我是小哥谈。YOLOv5基础知识入门系列、YOLOv5源码中的参数超详细解析系列、YOLOv5入门实践系列、YOLOv5论文作图教程系列和YOLOv5算法改进系列学习完成之后,接着就进入YOLOv5项目实战系列了。🎉为了让大家能够牢固地掌握YOLOv5算法,本系列文章就通过一个…

高级二-十进制转换算法

输入二进制数字符串&#xff0c;按二进制数位权重计算&#xff0c;输出十进制数。 (本笔记适合熟悉二进制数和字符串的 coder 翻阅) 【学习的细节是欢悦的历程】 Python 官网&#xff1a;https://www.python.org/ Free&#xff1a;大咖免费“圣经”教程《 python 完全自学教程…

Excel多线程导入数据库

文章目录 Excel多线程导入数据库1. CountDownLatch2.多线程导入数据库 Excel多线程导入数据库 书接上文 Excel20w数据5s导入 1. CountDownLatch CountDownLatch 维护了一个计数器&#xff0c;初始值为指定的数量。当一个或多个线程调用 await() 方法时&#xff0c;它们会被阻…

Dapper中使用字符串作为动态参数查询时,结果不是预期的问题

1、如下图&#xff0c;c.industryId作为string类型当作参数传递&#xff0c;解析时会加单引号&#xff0c;即&#xff1a;”c.industryId“&#xff0c; 生成的查询语句就会变成 -- 这里把c.IndustryGroup 当成实际的值所以会查询不出数据 select b.Name,COUNT(c.Id) Num …

驱动作业10.23

现象 test.c #include <stdlib.h> #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/ioctl.h> #include <fcntl.h> #include <unistd.h> #include <string.h> #include "head.h"in…

潮玩宇宙源码开发:开启全新的数字潮流时代

随着数字技术的飞速发展和人们对于娱乐需求的不断提升&#xff0c;潮玩宇宙源码开发逐渐成为了新的热门话题。潮玩宇宙是一个集潮流、艺术、科技于一体的数字娱乐新领域&#xff0c;通过将虚拟现实、增强现实等技术融入传统玩具设计中&#xff0c;为玩家们带来了全新的互动体验…

从零开始 Spring Cloud 15:多级缓存

从零开始 Spring Cloud 15&#xff1a;多级缓存 多级缓存架构 传统的缓存使用 Redis&#xff0c;大致架构如下&#xff1a; 这个架构存在一些问题&#xff1a; 请求要经过Tomcat处理&#xff0c;Tomcat的性能成为整个系统的瓶颈 Redis缓存失效时&#xff0c;会对数据库产生冲…