【C++高阶(二)】熟悉STL中的map和set --了解KV模型和pair结构

💓博主CSDN主页:杭电码农-NEO💓

⏩专栏分类:C++从入门到精通⏪

🚚代码仓库:NEO的学习日记🚚

🌹关注我🫵带你学习C++
  🔝🔝


在这里插入图片描述

map和set

  • 1. 前言
  • 2. map和set介绍
  • 3. pair结构介绍
  • 4. set结构详解
  • 5. map结构详解
  • 6. multimap和multiset
  • 7. map和set实战演练
  • 8. 总结

1. 前言

在学习了二叉搜索树后,现在
就可以来学习map和set了,虽然
它们的底层是红黑树结构,但是红黑树
的本质也是一颗二叉搜索树!

本质重点:

本篇文章着重讲解map和set的
使用方法以及一些特性,以及讲解
muti为前缀的map/set和普通map/set
的区别,其中会学到一个重要的结构
pair,它会伴随我们很久


2. map和set介绍

set是key模型,本质是确定一个
元素在不在此容器中,也就是说
set中存储的是一个单一数据

map和set的区别就是,map中存储
的并不是一个单一数据,而是存储了
一个pair结构!(后面会讲解)

在这里插入图片描述
在这里插入图片描述

map的模板参数中有key和T
而set的模板参数只有T

set和map结构中遍历出来是
数据有序并且去重的!

map和set都只支持增删查,不支持改!


3. pair结构介绍

pair结构实际上是一个键值对
以下是对于键值对的介绍:

在这里插入图片描述

这个类的代码大概是这样的:

template <class T1, class T2>
struct pair
{T1 first;T2 second;pair(): first(T1()), second(T2()){}pair(const T1& a, const T2& b): first(a), second(b){}
};

它实际上就是封装了两个可以是不同
类型的数,它可以用作中英字典,存储
pair<string,string>的结构,first存储中文
second存储对应的英文解释,非常好用!

map中存储的就是pair结构,所以
map也叫存储的KV模型,因为first和
second对应key和value

map的三种常见使用方法:

1. 方法一: 定义pair对象后插入

map<string,string> dict;
pair<string,string> kv1("排序","sort");
pair<string,string> kv2("左边","left");
dict.insert(kv1);
dict.insert(kv2);

2. 方法二: 使用匿名对象插入

map<string,string> dict;
dict.insert(pair<string,string>("排序","sort"));
dict.insert(pair<string,string>("左边","left"));

3. 方法三: 使用make_pair插入

map<string,string> dict;
dict.insert(make_pair("排序","sort"));
dict.insert(make_pair("左边","left"));

make_pair是最好用的方法!


4. set结构详解

在这里插入图片描述

先看set的第二个模板参数是less
是不是很熟悉?set默认情况下遍历
出来是升序,但是如果定义对象时显示
传参greater,就是降序!

set<int,greater<int>> s;

set的插入函数insert
在这里插入图片描述

插入我们需要关心三点:
一是插入可以不用写pos,直接插入
二是可以插入一段迭代器区间
三是插入的返回值也是一个pair结构
pair中存储了布尔类型和迭代器,分别
代表此次插入是否成功,若成功则返回
被插入元素迭代器的位置

set的查找和删除函数find,erase
在这里插入图片描述

在这里插入图片描述


5. map结构详解

在这里插入图片描述

set是没有支持方括号的
而map支持了,所以先讲解方括号的使用

map的方括号用法:
先看文档:
在这里插入图片描述
在这里插入图片描述

map的方括号设计的十分巧妙
它的参数的pair中的first,返回值
是pair中的second,并且它返回的是
引用,可以根据first修改second
它可以用来计数,请看如下demo代码:

统计水果的数量:

string arr[]={"苹果","西瓜","香蕉","苹果","西瓜","西瓜","西瓜","苹果"};
map<string,int> countmap;
for(auto str : arr)
{countmap[str]++;
}

请再看文档的详细信息:

在这里插入图片描述

也就是说,方括号自带插入功能,当
出现第一个"西瓜"时,会自动把"西瓜"
插入到map中,第二次遇见"西瓜"时,
会将西瓜的计数++变成2

map的删除和查找:
由于map的插入在前面已经讲解过了
这里只讲解删除和查找

在这里插入图片描述
在这里插入图片描述

erase和find传参只用传pair中的first
类型的参数,即可完成任务,并且find的
返回值和set的find是一样的,一个意思


6. multimap和multiset

map和set的遍历是有序并且去重的
也就是说里面没有相同的元素,但是
STL提供了multimap和multiset
它们允许存在相同的元素!

在这里插入图片描述
在这里插入图片描述

由于支持元素冗余
所以multimap不支持方括号了!

当我们插入相同的数据时,它也会保存

在这里插入图片描述


7. map和set实战演练

请看下面的力扣题目:

在这里插入图片描述

力扣692题

大家先思考一下对策吧

题目解析:

本题目不仅仅要找出前k个高频的单词
并且还要按照字典序来排序,也就是说,
要满足两个排序的条件:字符串出现的次数
和字符串在字典中的顺序!

想到要计数,当然是用map啦!

map<string,int> mpcount;
for(auto str : words)mpcount[str]++;

两个细节问题以及结论

  • map计数后,只需以map中的second
    作为基准来排序即可得到前k个高频

  • map本身的遍历就是有序的,并且此
    顺序刚好是字典序(以first排序的)

结论:只需使用一个排序算法,在不打乱
map原本排序的情况下,以map中的
second为基准排个序,即可得到我们
想要的答案,所以关键是要使用稳定
的排序算法!

库中稳定的排序算法:stable_sort

在这里插入图片描述

下面是所有的代码,不懂可以私信我

class Solution {
public:struct _compare{bool operator()(pair<string,int> p1,pair<string,int> p2){return p1.second>p2.second;}};vector<string> topKFrequent(vector<string>& words, int k) {map<string,int> mpcount;for(auto str : words)mpcount[str]++;vector<pair<string,int>> tmp;auto it = mpcount.begin();while(it!=mpcount.end()){tmp.push_back(*it);it++;}_compare com;vector<string> ret;stable_sort(tmp.begin(),tmp.end(),com);for(int i=0;i<k;i++)ret.push_back(tmp[i].first);return ret;}
};

8. 总结

熟悉map和set的使用在平常做题
时会有大用处,虽然平时用的更多的
是unordered_map/set,但是它们的
使用方法基本一致,学到就是赚到!


🔎 下期预告:AVL树深度剖析 🔍

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

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

相关文章

多租户和单租户权限设计的区别

近些年&#xff0c;随着技术和需求的发展&#xff0c;sass已经成为普遍现象&#xff0c;同时就出现了多租户概念&#xff0c;那么什么是多租户呢&#xff1f; 相较于传统企业的应用&#xff0c;只有一个企业在使用这一个系统&#xff0c;和别的企业无关&#xff0c;每次有一个…

一起学docker系列之二深入理解Docker:基本概念、工作原理与架构

目录 前言1 Docker的基本概念2 Docker的基本组成3 docker工作原理4 docker架构5 Docker详细工作过程结语 前言 在当今的软件开发和部署中&#xff0c;Docker已经成为一种不可或缺的工具。它简化了应用程序的打包、交付和运行&#xff0c;同时提供了强大的隔离性和可移植性。本…

c语言中链栈的基本操作

链栈是一种特殊的链表&#xff0c;其基本操作包括&#xff1a; 初始化&#xff1a;创建一个空的链栈。 判断是否为空&#xff1a;检查链栈中是否有元素。 入栈&#xff1a;在链栈的栈顶添加一个元素。 出栈&#xff1a;删除链栈的栈顶元素&#xff0c;并返回该元素的值。 获…

Java学习笔记(七)——面向对象编程(中级)

一、IDEA &#xff08;一&#xff09;常用的快捷键 &#xff08;二&#xff09;模版/自定义模版 二、包 &#xff08;一&#xff09;包的命名 &#xff08;二&#xff09;常用的包 &#xff08;三&#xff09;如何引入&#xff08;导入&#xff09;包 &#xff08;四&am…

win10 安装 node.js

要在你的系统上安装 Node.js&#xff0c;你可以按照以下步骤进行&#xff1a; 1. 打开 Node.js 官方网站&#xff1a;https://nodejs.org/ 2. 在首页上&#xff0c;你会看到两个版本的 Node.js 可供下载&#xff1a;LTS 版本和 Current 版本。LTS 版本是长期支持版本&#xff…

每日一题(LeetCode)----数组--长度最小的子数组的相关题(一)

每日一题(LeetCode)----数组–长度最小的子数组的相关题&#xff08;一&#xff09; 1.题目&#xff08;904. 水果成篮&#xff09; 你正在探访一家农场&#xff0c;农场从左到右种植了一排果树。这些树用一个整数数组 fruits 表示&#xff0c;其中 fruits[i] 是第 i 棵树上的…

「Verilog学习笔记」用优先编码器①实现键盘编码电路

专栏前言 本专栏的内容主要是记录本人学习Verilog过程中的一些知识点&#xff0c;刷题网站用的是牛客网 分析 用此编码器实现键盘的编码电路。 注意&#xff1a;编码器的输出是低电平有效&#xff0c;而键盘编码电路输出的是正常的8421BCD码&#xff0c;是高电平有效。因此将编…

ElasticSearch 安装(单机版本)

文章目录 ElasticSearch 安装&#xff08;单机版本&#xff09;环境配置下载安装包调整系统参数安装启动并验证 ElasticSearch 安装&#xff08;单机版本&#xff09; 此文档演示 ElasticSearch 的单机版本在 CentOS 7 环境下的安装方式以及相关的配置。 环境配置 Linux 主机一…

反向传播详解BP

误差反向传播&#xff08;Back-propagation, BP&#xff09;算法的出现是神经网络发展的重大突破&#xff0c;也是现在众多深度学习训练方法的基础。该方法会计算神经网络中损失函数对各参数的梯度&#xff0c;配合优化方法更新参数&#xff0c;降低损失函数。 BP本来只指损失…

OpenAI暂停ChatGPT Plus新用户注册;迷宫与图神经网络

&#x1f989; AI新闻 &#x1f680; OpenAI暂停ChatGPT Plus新用户注册&#xff0c;考虑用户体验 摘要&#xff1a;OpenAI决定暂停ChatGPT Plus新用户注册&#xff0c;以应对开发日后使用量激增带来的压力&#xff0c;确保每个人都能享受良好的体验。根据调查机构Writerbudd…

下载huggingface预训练模型到本地并调用

写在前面 在大模型横行的时代&#xff0c;无法在服务器上连接外网的研究僧真的是太苦逼了&#xff0c;每次想尝试类似于CLIP&#xff0c;BLIP之类的大模型都会得到“requests.exceptions.ConnectionError: (MaxRetryError("HTTPSConnectionPool(host‘huggingface.co’, …

LeetCode-2760. 最长奇偶子数组-滑动窗口暴力

Problem: 2760. 最长奇偶子数组 每日一题。实习第10天记录。 文章目录 思路Code 思路 注意用条件找r。 Code class Solution {public int longestAlternatingSubarray(int[] nums, int threshold) {int len nums.length;int l, r;int res 0;for (l 0; l < len; l) {// 定…

Datawhale智能汽车AI挑战赛

1.赛题解析 赛题地址&#xff1a;https://tianchi.aliyun.com/competition/entrance/532155 任务&#xff1a; 输入&#xff1a;元宇宙仿真平台生成的前视摄像头虚拟视频数据&#xff08;8-10秒左右&#xff09;&#xff1b;输出&#xff1a;对视频中的信息进行综合理解&…

【解决方案】危化品厂区安防系统EasyCVR+AI智能监控

危化品属于危险、易燃易爆、易中毒行类&#xff0c;一旦在生产运输过程中发生泄漏后果不堪想象&#xff0c;所以危化品的生产储存更需要严密、精细的监控&#xff0c;来保障危化品的安全。EasyCVRTSINGSEE青犀AI智能分析网关搭建的危化品智能监控方案就能很好的为危化品监管保驾…

基于STC12C5A60S2系列1T 8051单片机的数模芯片DAC0832实现数模转换应用

基于STC12C5A60S2系列1T 8051单片的数模芯片DAC0832实现数模转换应用 STC12C5A60S2系列1T 8051单片机管脚图STC12C5A60S2系列1T 8051单片机I/O口各种不同工作模式及配置STC12C5A60S2系列1T 8051单片机I/O口各种不同工作模式介绍数模芯片DAC0832介绍通过按键调节数模芯片DAC0832…

微信小程序微信用户授权登录怎么在小程序上和钉钉相关联

要在微信小程序上实现微信用户授权登录并与钉钉相关联&#xff0c;你需要执行以下步骤&#xff1a; 钉钉开放平台注册应用&#xff1a;在钉钉开放平台上注册一个应用&#xff0c;获取到相应的AppID和AppSecret。 微信小程序授权登录&#xff1a;在微信小程序中使用wx.login接口…

WPF下实现拖动任意地方都可以拖动窗口

首先在xaml中添加事件 <Window PreviewMouseLeftButtonDown"Window_PreviewMouseLeftButtonDown"PreviewMouseMove"Window_PreviewMouseMove"PreviewMouseLeftButtonUp"Window_PreviewMouseLeftButtonUp"/>然后脚本输入 Point _pressedP…

【Spring进阶系列丨第二篇】Spring中的两大核心技术IoC(控制反转)与DI(依赖注入)

前言 我们都知道Spring 框架主要的优势是在 简化开发 和 框架整合 上&#xff0c;至于如何实现就是我们要学习Spring 框架的主要内容&#xff0c;今天我们就来一起学习Spring中的两大核心技术IoC&#xff08;控制反转&#xff09;与DI&#xff08;依赖注入&#xff09;。 文章目…

【数据结构】别跟我讲你不会冒泡排序

&#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前正在学习c和算法 ✈️专栏&#xff1a;数据结构 &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章有啥瑕疵 希望大佬指点一二 如果文章对你有帮助…

【6】Spring Boot 3 集成组件:knift4j+springdoc+swagger3

目录 【6】Spring Boot 3 集成组件&#xff1a;knift4jspringdocswagger3OpenApi规范SpringFox Swagger3SpringFox工具&#xff08;不推荐&#xff09; Springdoc&#xff08;推荐&#xff09;从SpringFox迁移引入依赖配置jAVA Config 配置扩展配置&#xff1a;spring securit…