【C++】map|set|原理使用|multiset|multimap|operator[]|

news2024/12/25 12:23:14

目录

 

一,关联式容器

二,键值对

2.1为什么使用键值对

2.2make_pair()

三,STl关联容器

四,set 

4.1模板参数 

 4.2默认构造

 4.3使用

去重功能和自动排序

4.4增删查

insert

find

erase

五,multiset 

count

erase

find 

六,map 

6.1默认构造 

特性 

6.2使用 

insert

operator[]

示例

方法1

方法2 

 七,multimap


一,关联式容器

  • 在STL中vector,list,stack,queue等都属于序列式容器,底层是线性结构,里面存储的是元素本身;
  • 关联式容器也是用来存储数据的,与序列式容器不同的是,其里面存储的是 <key, value> 结构的键值对,在数据检索时比序列式容器效率更高,set map 便是关联式容器 

二,键值对

  键值对是用来表示具有一一对应关系的一种结构,该结构中一般只包含两个成员变量keyvalue

  • key代表键值;
  • value表示与key对应的信息       pair - C++ Reference (cplusplus.com)

set map 就使用了键值对,这个键值对名为 pair,它是一个 struct 定义的类模板,即可以在外部访问 pair里面的成员变量 

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

所以pair就是一个类模板,根据<>里的两个参数来实例化类,第一个参数表示key,第二个表示value

  • pair的两个成员变量first表示key,second表示value 

2.1为什么使用键值对

为什么不直接在容器中定义 key value 变量,而是将 key value 合并到 pair 中整体作为一个类型来使用呢?

        这是因为 C++ 一次只能返回一个值,如果我们将 key value 单独定义在容器中,那么我们就无法同时返回 key value ;而如果我们将 key value 定义到另一个类中,那我们就可以直接返回 pair ,然后再到 pair 中分别去取 first second 即可。

2.2make_pair()

该函数是用来制作一个pair类型的匿名对象的:

make_pair - C++ Reference (cplusplus.com)

	map<string, string> dict;
	pair<string, string> kv1("sort", "排序");
	//三种插入
	
	dict.insert(kv1);		//有名
	dict.insert(pair<string,string>("left", "左边"));	//匿名
	dict.insert(make_pair("right", "右边"));	//更快速的匿名

make_pair()是为了让我们更加方便的使用键值对。

三,STl关联容器

  • STL关联容器有两种结构:树形结构,哈希结构;
  • 常见的树形结构关联容器有:mapsetmultimapmultiset;
  • 这四种容器的共同点是:使用平衡搜索树(即红黑树)作为其底层结果,容器中的元素是一个有序的序列

四,set 

set是按照一定次序存储元素的容器,其底层是一棵平衡二叉搜索树 (红黑树);

  由于二叉搜索树的每个节点的值满足左孩子 < 根 < 右孩子,并且二叉搜索树中没有重复的节点,所以set可以用来排序、去重和查找,同时由于这是一棵平衡树,所以 set查找的时间复杂度为 O(logN),效率非常高;

  • map等容器不同,set存储的元素其实只有value,在底层是<value, value>
  • 所以在插入元素时,只需要提供value即可,不需要构造键值对。使用set的迭代器进行遍历set时,会得到一个有序的序列。这是因为遍历的方式其实是二叉搜索树的中序遍历。
  • set中的元素也不允许修改,因为这可能会破坏搜索树的结构,但是 set允许插入和删除。

4.1模板参数 

class T:是 set 中存放元素的类型,实际在底层存储 <value, value> 的键值对 ;

class Compare = less<T>compare是仿函数,set中元素默认按照小于来比较(less);

class Alloc = allocator<T>:控制set的空间管理方式,使用STL提供的空间管理配置器.

 4.2默认构造

set::set - C++ Reference (cplusplus.com)

set提供了三种构造:默认空构造,迭代器区间构造和拷贝构造;

	set<int> s1;

	//迭代器区间构造
	s1 = { 1,2,3,4,5 };
	set<int> s2(s1.begin(),s1.end());

	//拷贝构造
	set<int> s3(s2);

 4.3使用

去重功能和自动排序

  • set具有降重的功能,当插入的数据已经存在时就不会再插入
  • 在打印set中的数据时,我们发现打印出来的结果是升序的,在二叉搜索树中,采用中序遍历的方式打印出来的结果就是升序的。

4.4增删查

insert

有三种插入方式,不建议用指定位置插入,有可能会破坏原二叉搜索结构

set::insert - C++ Reference (cplusplus.com)

find

 查找容器中是否存在某个特定的元素

  • 如果存在,返回该位置所在的迭代器;
  • 如果不存在,则返回set的结束位置的迭代器end()。

count 函数与其类似,只不过返回的是1和0,返回的是数字

set::count - C++ Reference (cplusplus.com)

 

erase

删除指定位置的值;set::erase - C++ Reference (cplusplus.com)

注:

  • 第二个重载函数,由于set中没有重复值,所以返回的值就是1。

  • 使用迭代器位置删除时,先find找到位置,再erase;
  •  使用指定数据的erase时,删除成功返回1,如果不存在则返回0。
  •  使用迭代器区间的erase时,将区间内的数据全部删除。

五,multiset 

成员函数和set一样,区别在于multiset支持数据重复,set不可以;

multiset - C++ Reference (cplusplus.com)

  • set:排序 + 降重
  • multiset:排序(不降重)

count

setcount成员函数和find功能类似,但是在multiset中它就有了它的作用。

multiset::count - C++ Reference (cplusplus.com)

erase

multiset::erase - C++ Reference (cplusplus.com)

 multiset中没有100,所以返回值就是0。 

find 

 multiset容器中存在重复元素,使用查找find函数,返回的是中序遍历中第一个元素;

multiset::find - C++ Reference (cplusplus.com)

其它函数基本上set一模一样了 

六,map 

map和set一样,也是一个关联式容器,底层是二叉搜索树。

map - C++ Reference (cplusplus.com)

  • 键值对映射 :map中的元素是一对键值对(pair),每一个key都有一个value对应。
  • 自动排序:与set类似,map中的元素在插入的同时会进行排序,默认情况下是key小的排在前面。
  • 唯一键:每个键在map中都是唯一的。
  • map查找的时间复杂度是O(logn).
  • 迭代器支持:支持使用迭代器来遍历map中的元素。本质上是搜索二叉树的中序遍历
  • 底层是用二叉搜索树(红黑树)实现的。
  • 可以使用[key]访问对应的value;(operator[])

6.1默认构造 

  • 使用默认构造函数创建的map是空的。
  •  插入键对值时,使用make_pair创建匿名对象更加方便。

特性 

  •  map具有降重功能,和set一样。
  •  不能插入相同的键值对,和set一样,map不支持重复数据。
  •  不能插入key值相同,val值不同的键值对。
  • map中虽然存放的是键值对,但是它的判断逻辑都只看key值,也就是first所表示的变量。
  • map也具有排序 + 降重的功能,依据只看key值而不管value值。

6.2使用 

insert

  • 参数类型 value_type pair<const key_type, mapped_type> 进行 typedef 得到的,也就是说参数是一个键值对,并使用引用传参
  • insert 第一个(框起来的)的返回类型为 pair<iterator, bool>
  • pair<iterator, bool>第一个iterator是迭代器;
    • 第二个是 bool,用于反映是否插入成功,成功返回true,否则返回false
  • 如果插入成功(即元素不存在进行插入):返回为 pair<iterator, true>;迭代器返回的是新插入元素位置的迭代器(pair
  • 如果插入失败(即元素已经存在):返回为 pair<iterator, false>,迭代器返回的是已存在元素位置的迭代器(pair);
  • map::insert - C++ Reference (cplusplus.com)

operator[]

通过键来访问或插入元素:

  • 如果键存在,它将返回对应的值的引用,即返回 Key 值的引用;
  • 如果键不存在,它会自动插入一个键值对,其中值部分为默认构造的值,并返回这个新插入值的引用。

:即使没有为元素分配映射值(即不给T传值,T为空),该元素使用其默认构造函数构造,插入新元素后,这会将容器大小增加1

map::operator[] - C++ Reference (cplusplus.com)

  • at 成员函数功能与 [] 类似,但是在具有键的元素存在时具有相同的行为(即查找的元素 Key 是存在的时候,at [] 的功能是一样的);
  • 但当不存在时抛出异常(即查找的 Key 不存在,[] 的功能是把这个 Key 直接插入map中,但是 at 是抛异常,不会进行插入);
示例

计算水果数量 

方法1

方法2 

总结

  • [] 的功能是 查找+修改+插入 (修改的原因是 [] 返回 mapped_type(T)值的引用)
  • at 的功能是 查找+修改(不支持插入)

 七,multimap

multimapmap的不同就是:

  • map中的key是唯一的,而multimapkey是可以重复的

multimap中没有重载 operator[] 操作,因为 multimapkey可能不唯一;(multimap不支持[key]操作);

使用时与map包含的头文件相同

 

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

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

相关文章

面试官:使用 xxl-job 怎样解决任务重叠问题?

大家好&#xff0c;我是君哥。今天分享批量任务的重叠问题。 面试官&#xff1a;聊聊你用过的任务调度框架&#xff1f; 我&#xff1a;目前任务调度框架的选择有很多&#xff0c;比如业内熟悉的 QuartZ&#xff0c;Spring Batch&#xff0c;xxl-job&#xff0c;以及新一代的…

从零到一:同城代驾系统源码开发全流程详解

本篇文章&#xff0c;小编将详细解析同城代驾系统源码开发的全流程&#xff0c;从需求分析到最终上线&#xff0c;帮助你从零到一构建完整的系统。 一、需求分析与市场调研 对于同城代驾系统&#xff0c;首先要明确的是目标用户群体&#xff0c;如城市白领、商务人士或家庭用…

文件操作与IO(上)

✨个人主页&#xff1a; 不漫游-CSDN博客 目录 一、认识文件 文件存储 文件路径 绝对路径 相对路径 文件种类 二进制文件 文本文件 文件系统操作 经典面试题 一、认识文件 想必文件大家都不陌生&#xff0c;文件是存储在计算机系统中的数据集合&#xff0c;它可以包…

JavaScript基础——JavaScript运算符

赋值运算符 算术运算符 一元运算符 三元/三目运算符 比较运算符 逻辑运算符 运算符优先级 在JavaScript中&#xff0c;常见的运算符可以包括赋值运算符、一元运算符、算术运算符&#xff08;二元运算符&#xff09;、三元/三目运算符、比较运算符、逻辑运算符等&#xff0…

centos7安装zabbix

可以联网的centos7系统 关闭防火墙 selinux也关了 1、配置镜像源 wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo wget -O /etc/yum.repos.d/epel.repo https://mirrors.aliyun.com/repo/epel-7.repo2、安装nginx并配置 yum ins…

uniapp全局分享功能实现方法(依赖小程序右上角的分享按钮)

1、uniapp开发小程序时默认是关闭分享功能的。点击右上角三个点可查看&#xff0c;效果图如下&#xff1a; 2、在utils文件夹下新建share.js文件&#xff0c;名字任起。&#xff08;使用的是全局分享&#xff0c;因为一个一个页面的去分享太麻烦且没必要。&#xff09; export…

万字长文分享快手 Kolors 可图大模型应用实践

导读 在企业提效方面&#xff0c;多模态能力同样具有重要意义。在 AICon 北京站活动中&#xff0c;快手「可图」大模型负责人李岩分享了主题为《快手「可图」文生图大模型应用实践》的演讲&#xff0c;以下为李岩演讲内容&#xff5e;期待对你有所启发&#xff01; 一、基座模…

docker部署java项目(war包方式)

场景描述:java项目war包,在开发开电脑上使用dockerfile构建镜像,上传镜像到客户服务器中使用docker加载docker镜像,然后部署。 目录 一、本地环境安装 docker git 二、服务器环境安装 docker 三、构建docker镜像(win系统) 四、注意事项 (1)系统架构 (2)使…

线程(Pthread)

目录 多线程模式下cpu如何分配 这两种线程的优缺点 多个线程在进程中共享资源有哪些 非共享资源 线程函数&#xff08;NPTL API&#xff09; 线程分离态 线程退出方式 关于线程的能力 线程属性 线程是大多数操作系统支持的调度单位&#xff0c;执行单元&#xff0c;某…

【全国大学生电子设计竞赛】2022年F题

&#x1f970;&#x1f970;全国大学生电子设计大赛学习资料专栏已开启&#xff0c;限时免费&#xff0c;速速收藏~

RabbitMQ高级特性 - 事务消息

文章目录 RabbitMQ 事务消息概述实现原理代码实现不采用事务采用事务 RabbitMQ 事务消息 概述 RabbitMQ 的 AMQP 协议实现了事务机制&#xff0c;允许开发者保证消息的发送和接收时原子性的&#xff0c;也就是说&#xff0c;要么消息全都发送成功&#xff0c;要么全都发送失败…

《python语言程序设计》2018版第6章第27题双素数是指一堆差值为2的素数。

水平的原因做不到答案那种输出 def is_prime(number):divisor 2while divisor < number / 2:if number % divisor 0:return Falsedivisor 1return Truedef print_prime_numbers(number_of_primes):count 0number 2while number < number_of_primes:if is_prime(numb…

六、GD32 MCU 选项字节设置及解除方法

您在使用GD32过程中是否遇到过芯片反复复位&#xff0c;代码无法更新&#xff0c;代码一直执行在0x1fffxxxx区域&#xff0c;或代码执行在SRAM区域的情况&#xff1f;如果有遇到这类现象是否找到原因呢&#xff1f;如果没找到是否检查过选项字节是否正常呢&#xff1f;这一章节…

C++ | 类和对象(下)(static成员、友元、内部类、匿名对象)

目录 ​编辑 static成员 static性质简介 static属于整个类&#xff0c;属于所有对象 static成员的声明与定义 static函数 友元friend 友元特性简介 友元关系讲解 内部类 特性一 特性二 匿名对象 结语 static成员 static性质简介 static成员在类里面是非常独特的…

ContentProvider的相关知识总结

1.ContentProvider概念讲解&#xff1a; 2.使用系统提供的ContentProvider 其实很多时候我们用到ContentProvider并不是自己暴露自己的数据&#xff0c;更多的时候通过 ContentResolver来读取其他应用的信息&#xff0c;最常用的莫过于读取系统APP&#xff0c;信息&#xff0c…

Kubernetes中的CRI、CNI与CSI:深入理解云原生存储、网络与容器运行时

引言 随着云原生技术的飞速发展&#xff0c;Kubernetes&#xff08;简称K8s&#xff09;作为云原生应用的核心调度平台&#xff0c;其重要性日益凸显。K8s通过开放一系列接口&#xff0c;实现了高度的可扩展性和灵活性&#xff0c;其中CRI&#xff08;Container Runtime Inter…

使用归一化连接计数的胸部CT成像:预测CanCOLD研究中的肺气肿进展| 文献速递-AI辅助的放射影像疾病诊断

Title 题目 CT Chest Imaging Using Normalized Join-Count: Predicting Emphysema Progression in the CanCOLD Study 使用归一化连接计数的胸部CT成像&#xff1a;预测CanCOLD研究中的肺气肿进展 Background 背景 Pre-existing emphysema is recognized as an indicator…

【C++】------继承(一)

目录 前言 一、概念与定义 Ⅰ、是什么&#xff1f; Ⅱ、定义 1.定义格式&#xff1a; 2.继承方式和访问限定符 3.基类&#xff08;父类&#xff09;成员访问方式的变化 二、父类与子类的赋值转化 基本认识 原理 三、 继承中的作用域 四、子类(派生类)的默认成员函…

Spring中是如何实现IoC和DI的?

前言&#xff1a;在前一篇文章中对于IoC的核心思想进行了讲解&#xff0c;而本篇文章则从Spring的角度入手&#xff0c;体会Spring对于IoC是如何实现的。 如果对IoC还有不太了解的可以阅读上一篇文章&#xff0c;相信一定会带来全新的收获&#xff1a;什么是IoC&#xff08;控制…

5.5软件工程-系统测试

系统测试 意义和目的原则测试过程测试策略测试方法练习题 测试用例设计黑盒测试等价类划分边界值分析错误推测因果图 白盒测试逻辑覆盖循环覆盖基本路径测试法 练习题 调试软件度量练习题 考点少&#xff0c;知识点多 意义和目的 系统测试的意义&#xff1a;系统测试是为了发现…