set和map结构的使用

news2024/11/17 13:39:55

个人主页:敲上瘾-CSDN博客

个人专栏:游戏、数据结构、c语言基础、c++学习、算法

目录

一、序列式容器和关联式容器

二、set和multiset

1.insert

2.erase

3.find

4.count

三、map和mapmulti

1.pair

2.insert

3.find

4.operator[ ]

5.erase

6.lower_bound和upper_bound

四、习题

1.环形链表||

1.算法原理

2.代码编写

2.随机链表的复制

​编辑

1.算法原理

2.代码编写


一、序列式容器和关联式容器

        在正式讲解set和map之前需要先了解这个概念——序列式容器和关联式容器。比如string、vector、list、deque等这些储存结构都是序列式容器。序列式容器的特点是它们的逻辑结构都是线性的,而且数据之间都没有关联性,对一个数据的增删查并不对其他数据造成影响,也不会对这个结构造成影响。

        而关联式容器就恰好相反,它的逻辑结构是非线性的,而且数据之间的关联性非常强,对其中一个数据进行改变会对整个数据结构造成影响,比如set,setmulti,map,mapmulti,undered_set,undered_map。

        这一章的主角set和map它们是一种树形结构,它们的底层是红黑树,即⼀颗平衡⼆叉搜索树
。不过这一章主要是来讲它们的使用,对底层的结构并不做探讨。

二、set和multiset

        首先区分一下set和multiset:set中一个值只能出现一次(即同一个key只能在set里面插入一个)。multiset内允许储存多个相同的值。

set的学习网址:set - C++ Reference (cplusplus.com)

1.insert

        insert接口主要作用是来插入元素的,它支持直接插入某一个元素,也支持插入某个迭代器区间。

如下:

	set<int> st;
	st.insert(999);
	vector<int> arr = { 1,5,3,2 };
	st.insert(arr.begin(), arr.end());

2.erase

        erase支持删除一个值,删除一个迭代器区间或一个迭代器。

如下:

st.erase(7);//删除某个值
st.erase(st.begin());//删除最小值
st.erase(st.begin(), st.end());//删除整个区间

注意:对于set迭代器的遍历是中序遍历,所以迭代器遍历结果是有序的。 

3.find

        find的使用比较简单,传入一个值然后会返回一个该值的迭代器,不存在则返回空,就不再多讲。

4.count

        count接口是用来返回set / multiset / map / multimap中某一个数据出现的个数,也可用来查找某个数据是否存在。

三、map和mapmulti

map的学习网址:map - C++ Reference (cplusplus.com)

        map和set的区别:set一块区域只储存一个关键字(记为key),而map储存的是一个key和value,key和value是一个映射关系,通过key可以找到对应的vaule。而它们的函数接口的用法都一样就不分开讲。

        map和multimap:map中一个键值对(key和value)只能出现一次(即同一个键值对只能在map里面插入一个)。multiset内允许储存多个相同的键值对。

1.pair

 pair学习网址:pair - C++ Reference (cplusplus.com)

    pair是一种模板类型,用于存储一对值,其中这两个值可以是不同类型。它位于头文件 utility 中。使用 pair 可以非常方便地存储和操作一对相关联的数据,比如一个键(key)和一个值(value),这在许多算法和数据结构中都非常有用,如哈希表、映射(map)等。

    pair 有两个成员变量,通常称为 first 和 second,分别用来存储这一对值。这两个成员的类型可以不同,但它们都是在 pair 被声明时指定的。

pair有映射和集合的作用,标准库中的 mapmultimapunordered_map 和 unordered_multimap 等容器内部都使用 pair 来存储键值对。

2.insert

        因为map在做插入和各种处理时,key和value的关联性很强,而且如果kay和value分散开放的话会使map的迭代器无法获取到key和value的值。所以使用了pair结构,pair的作用相当于把key和value绑定在一起。

所以insert的插入方法有以下几种:

2.1.先创建一个pair变量并储入键值对,然后再利用插入map中。

map<string, string> dict;
pair<string, string> kv1("left", "左");
dict.insert(kv1);

 2.2.创建匿名pair对象插入map中

map<string, string> dict;
dict.insert(pair<string, string>("left", "左"));

2.3.使用make_pair 

map<string, string> dict;
dict.insert(make_pair("left", "左"));

make_pair这个接口的底层同样用了pair,不过它可以自动识别数据类型,减少了模板类型的填写。

2.4.c++11之后支持pair的隐式构造。

map<string, string> dict;
dict.insert({ "left", "左" });

        对于以上的几种插入,insert都会返回pair<interator, bool>,即如果插入失败,返回的就是nullptr和false,如果插入成功或该数据已经存在则返回该位置的迭代器和true。所以insert同时具备插入和查找功能。

注意在做迭代器遍历的时候,pair的first成员是key,second成员是value。

3.find

        map的查找呢是传入一个key值,然后对其查找,然后返回对应的迭代器,注意:map不支持对key进行修改,但支持对value进行修改。

4.operator[ ]

        这个运算符重载的功能比较全面,它既有查找的功能,也有修改和插入的功能。它需要传入一个key,注意只能是key,因为是要用key去查找。

如果找到则返回这个key对应的value的引用

如果没找到插入这个key然后返回对应的value的引用。

所以我们可以完成下面的操作:

map<string, string> dict;
dict["right"];//right不存在完成插入操作
dict["left"]="左边";//left不存在进行插入并且修改
dict["left"] = "左边,剩余的";//left存在完成查找并且修改

5.erase

        传入一个key,按中序遍历找到key并且删除所有key关键字的键值对。其他性质与set类似。

6.lower_bound和upper_bound

lower_bound 的作用:

    lower_bound 函数用于在一个有序器中查找第一个大于等于给定值的元素。它返回一个迭代器,指向该元素。如果容器中不存在大于等于给定值的元素,则返回指向容器末尾的迭代器。

upper_bound 的作用:

    upper_bound 函数用于在一个有序容器中查找第一个大于给定值的元素。它同样返回一个迭代器,指向该元素。如果容器中不存在大于给定值的元素,则返回指向容器末尾的迭代器。

    lower_bound 和 upper_bound 搭配使用可以确定一个左闭右开的迭代器区间。这个区间由 lower_bound 返回的迭代器(包含)和 upper_bound 返回的迭代器(不包含)界定。

这两个函数对于set、map、vector等等使用方法都是相同的。

四、习题

1.环形链表||

1.算法原理

        这个题是链表学习中的一个经典的题目,给一个链表然后判断这个链表是否有环,如果有环返回入环口处的节点,如果没有则返回空。

        方法一:快慢指针。该题可以用一个快慢指针同时从链表头开始走,如果快指针走到空节点还未与慢指针相遇,则该链表无环。如果快指针与慢指针相遇,则有环并记录相遇点,找两个速度相同的指针一个从头开始走,一个从相遇点开始走,那么它们相遇时的点就为环的入口点。这个算法比较难以想到,而且一眼难以看出它的正确性需要有严谨的证明。我在以下文章中有详细讲解:链表经典面试题-CSDN博客

        方法二:使用一个指针从链表的头走到尾,并且使用一个set容器,每走一步判断set中是否已存入该值,如果没有则存入,如果有那么这个链表一定有环并且该点就是环的入口点,直接返回该值即可。如果指针走到空依旧没有找到set中的重复值则这个链表不带环,返回空。该方法灵活运用了数据结构,而且很容易理解,相比上一个解法直接就是降维打击。

2.代码编写

class Solution {
public:
    ListNode *detectCycle(ListNode *head) 
    {
        set<ListNode*> pt;
        ListNode* cur=head;
        while(cur)
        {
            if(pt.count(cur)) return cur;
            else pt.insert(cur);
            cur=cur->next;
        }
        return nullptr;
    }
};

2.随机链表的复制

1.算法原理

        该题是对一个随机链表进行深拷贝,给一个链表要求原模原样拷贝一份,而这个题的难点并不在于拷贝节点本身,而是在于拷贝节点后random指向的节点是什么。尽管我们知道原链表的random指向什么但很难根据旧空间random的指向来判断新空间random的指向。不过因为旧空间与新空间有一个一一映射关系,所以我们可以使用一个map,key储存旧空间的值,value储存新空间的值。这个时候就非常好办只需旧空间的random找到指向的key就能找到新空间random应该指向的value。

2.代码编写

class Solution
{
public:
    Node* copyRandomList(Node* head)
    {
        map<Node*,Node*> mp;
        Node* cur=head;
        Node* rhead=nullptr,*ret=nullptr,*perv=nullptr;
        while(cur)
        {
            Node* ret=new Node(cur->val);
            if(rhead==nullptr) rhead=ret;
            else perv->next=ret;
            mp[cur]=perv=ret;
            cur=cur->next;
        }
        ret=rhead;
        cur=head;
        while(ret)
        {
            ret->random=mp[cur->random];
            ret=ret->next;
            cur=cur->next;
        }
        return rhead;
    }
};

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

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

相关文章

QT-自定义信号和槽对象树图形化开发计算器

1. 自定义信号和槽 核心逻辑&#xff1a; 需要有两个类&#xff0c;一个提供信号&#xff0c;另一个提供槽。 然后在窗口中将 信号和槽 链接起来。 示例目标&#xff1a; 创建一个 Teacher 类&#xff0c;提供信号。 创建一个 Student 类&#xff0c;提供槽。 实现步骤&…

策略路由控制选路

&#x1f423;个人主页 可惜已不在 &#x1f424;这篇在这个专栏 华为_可惜已不在的博客-CSDN博客 &#x1f425;有用的话就留下一个三连吧&#x1f63c; 目录 一、 实验拓扑 二、 实验简述 三、 实验配置 配置路由信息 配置控制选路 四、 实验验证 ​ 一、 实验…

「安装」 Windows下安装CUDA和Pytorch

「安装」 Windows下安装CUDA和Pytorch 文章目录 「安装」 Windows下安装CUDA和PytorchMac、Linux、云端Windows安装CUDA安装miniconda安装PyTorch测试总结 其他 Mac、Linux、云端 Mac、Linux、云端安装Miniconda和Pytorch的方法参考其他资料。 Windows 下面进行Windows下安装…

CSS选择器的全面解析与实战应用

CSS选择器的全面解析与实战应用 一、基本选择器1.1 通配符选择器&#xff08;*&#xff09;2.标签选择器&#xff08;div&#xff09;1.3 类名选择器&#xff08;.class&#xff09;4. id选择器&#xff08;#id&#xff09; 二、 属性选择器&#xff08;attr&#xff09;三、伪…

转行大模型的必要性与未来前景:迎接智能时代的浪潮

随着人工智能&#xff08;AI&#xff09;技术的迅猛发展&#xff0c;特别是大型语言模型&#xff08;LLM, Large Language Models&#xff09;的崛起&#xff0c;各行各业正迎来一场前所未有的技术革命。对于普通程序员而言&#xff0c;转行进入大模型领域不仅是对个人职业发展…

通配符与Powershell

通配符与正则表达式 通配符 通配符是一种特殊的语句&#xff0c;主要有*、?和[]&#xff0c;用来模糊搜索文件。 通配符表达意思举例说明*星号、匹配任何字符*.cpp匹配.cpp文件?问号、匹配任意一个字符*.?d匹配具有特定格式的文件[]中括号、匹配括号中的一个字符.[a-z]d代…

DC00020基于springboot新闻网站系统java web项目MySQL新闻管理系统

1、项目功能演示 DC00020基于springboot新闻网站系统java web项目MySQL 2、项目功能描述 基于springbootvue新闻网站包括用户和系统管理员两个角色。 2.1 用户功能 1、用户登录、用户注册 2、新闻信息&#xff1a;点赞、点踩、收藏、查看 3、用户分享&#xff1a;点赞、点踩…

分库分表还是分布式?如何用 OceanBase的单机分布式一体化从根本上解决问题

随着企业业务规模的不断增长&#xff0c;单机集中式的数据库系统逐渐难以承载企业日益增长的数据存储与处理需求。因此&#xff0c;MySQL 的分库分表方案成为了众多企业应对数据存储量激增及数据处理能力需求扩张的“止痛药”。尽管这一方案短期内有效缓解了企业面临的大规模数…

封装左侧抽屉可拖拽组件【可多个】

一、案例效果 二、案例代码 封装抽屉组件 <template><div class"drag-drawer"><div class"out-box" :style"style"><mtd-tooltip:content"collapse ? 展开面板 : 收起面板"class"tool-tip":placeme…

828华为云征文|部署敏捷项目管理系统工具 ZenTao

828华为云征文&#xff5c;部署敏捷项目管理系统工具 ZenTao 一、Flexus云服务器X实例介绍二、Flexus云服务器X实例配置2.1 重置密码2.2 服务器连接2.3 安全组配置2.4 Docker 环境搭建 三、Flexus云服务器X实例部署 ZenTao3.1 ZenTao 介绍3.2 ZenTao 部署3.3 ZenTao 使用 四、总…

云 安 全 (Cloud Security)

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 本人主要分享计算机核心技…

robomimic基础教程(四)——开源数据集

robomimic开源了大量数据集及仿真环境&#xff0c;数据集标准格式为HDF5 目录 一、基础要求 二、使用步骤 1. 下载数据集 2. 后处理 3. 训练 4. 查看训练结果 三、HDF5数据集结构与可视化 1. 数据集结构 &#xff08;1&#xff09;根级别&#xff08;data 组 group&a…

overlayscrollbars使用

官网 https://github.com/KingSora/OverlayScrollbars 使用 <link href"https://cdn.bootcdn.net/ajax/libs/overlayscrollbars/2.10.0/styles/overlayscrollbars.css" rel"stylesheet"> <script src"https://cdn.bootcdn.net/ajax/libs/…

AP配置(leaderAP组网模式)

1.前言 由于业务需求&#xff0c;临时组建一个网络环境使用 网络设备&#xff1a;华为 AirEngine 5762-10、5762S-12 2.网络结构 参考文档&#xff0c;使用leader ap组网模式 使用一台5862S-12作为leaderAP&#xff0c;AP通电后默认是fit模式&#xff0c;需要进入修改 如果…

HA Peer-mode非对称路由配置

目录 前言 一、组网拓扑 二、配置步骤 1.Hillstone-A 2.Hillstone-B 总结 前言 网络环境有非对称流量且需要双活部署时&#xff0c;防火墙可配置HA的peer-mode非对称路由模式进行实现。 一、组网拓扑 数据流量的路径是非对称的&#xff08;即 Flow0和Flow1是两条不同流量…

线性代数~行列式计算

来自b站博主&#xff0c;我爱一高数

【系统交付资料】软件文档交付清单整理套用原件(Word,PPT,Excel)

软件文档交付清单是指在软件开发项目完成后&#xff0c;开发团队需要准备的一份详细清单&#xff0c;用于确保交付的软件产品符合客户需求并达到预期的质量标准。以下是软件文档交付清单中可能包含的一些关键要素 软件资料清单列表部分文档清单&#xff1a;工作安排任务书&…

音视频入门基础:FLV专题(7)——Tag header简介

一、引言 从《音视频入门基础&#xff1a;FLV专题&#xff08;3&#xff09;——FLV header简介》中可以知道&#xff0c; 在FLV header之后&#xff0c;FLV文件剩下的部分应由PreviousTagSize和Tag组成。FLV文件 FLV header PreviousTagSize0 Tag1 PreviousTagSize1 Ta…

顺序表算法题 —— 移除元素、删除有序数组中的重复项、合并两个有序数组

目录 一、顺序表算法题 1、移除元素 2、删除有序数组中的重复项 3、 合并两个有序数组 二、顺序表问题与思考 一、顺序表算法题 1、移除元素 移除元素 - 力扣&#xff08;LeetCode&#xff09; 思路分析&#xff1a; 思路一&#xff1a;创建一个新数组&#xff0c;开辟…

828华为云征文|在Flexus X实例上安装JDK和Tomcat保姆教学

目录 一、Flexus云服务器X实例 1.1 Flexus X实例概述 1.2 Flexus X实例场景优势 1.3 其他型号与Flexus X实例比较 二、Flexus X实例上安装JDK 2.1 确定安装版本 2.2 yum命令直接安装 2.3 查看版本 三、Flexus X实例上安装tomcat 3.1 上传安装包到Flexus X实例服务器 …