【C++入门到精通】C++入门 —— map multimap (STL)

在这里插入图片描述

阅读导航

  • 前言
  • 一、map简介
  • 二、std::map
    • 1. std::map简介
    • 2. std::map使用
      • - 基本使用
      • - map模板参数说明
        • ⭕std::pair<const Key, T>
      • - map的构造函数
      • - map的迭代器
      • - map的容量与元素访问函数
        • 🍁容量函数
        • 🍁元素访问函数
    • 3. map的所有函数(表)
  • 三、std::multimap
    • 1. std::multimap简介
  • 四、std::map与std::multimap的比较
  • 温馨提示

前言

各位小伙伴们,在这个美好的中秋节来临之际,我衷心祝福你和你的家人度过一个幸福、团圆的时刻。愿明月的皎洁照耀你的每一天,团圆的月饼传递着我对你的思念和祝福。祝福你在中秋佳节里收获幸福与快乐,家庭和睦,心想事成。中秋快乐!

前面我们讲了C语言的基础知识,也了解了一些初阶数据结构,并且讲了有关C++的命名空间的一些知识点以及关于C++的缺省参数、函数重载,引用 和 内联函数也认识了什么是类和对象以及怎么去new一个 ‘对象’ ,也了解了C++中的模版,以及学习了几个STL的结构也相信大家都掌握的不错,接下来博主将会带领大家继续学习有关C++比较重要的知识点—— map & multimap (STL) 。下面话不多说坐稳扶好咱们要开车了😍

一、map简介

在C++中,map是一种关联容器,它提供了一种将键值对存储为有序集合的方式。每个键唯一地映射到一个值,因此可以使用键来高效地查找、插入和删除元素。其中map又分为mapmultimap,接下来博主将会带着大家认识一下这两个函数

🔴 官方文档 > 链接

在这里插入图片描述

二、std::map

1. std::map简介

⭕ 官方文档 > 链接

在这里插入图片描述

std::map是C++ STL提供的一种关联容器,它将键值对作为元素存储,并根据键的大小进行排序。每个键只能出现一次,即一个键最多只能映射到一个值。std::map提供了高效的插入、查找和删除操作,并支持多种方式遍历元素。

下面是std::map的一些重要特点:

  1. 插入元素时会自动根据键的大小进行排序
  2. 可以通过键来查找对应的值,时间复杂度为O(logN),其中N为元素的个数。
  3. std::map中删除元素也很容易,时间复杂度为O(logN)
  4. std::map可以用于各种类型的键和值,包括基本类型和用户定义类型。
  5. std::map的实现是基于红黑树的平衡二叉搜索树,因此插入、查找和删除的时间复杂度都是O(logN)。

2. std::map使用

- 基本使用

使用std::map非常简单,只需要包含头文件<map>,然后定义std::map对象并开始使用:

#include <map>std::map<int, std::string> myMap;
myMap[0] = "zero";
myMap[1] = "one";
std::cout << myMap[0] << std::endl; // 输出"zero"
std::cout << myMap[1] << std::endl; // 输出"one"

- map模板参数说明

template < class Key, class T, class Compare = less<Key>, class Alloc = allocator<pair<const Key,T> > > class map;
//模版说明
class Key                                   //map::key_type           
class T                                     //map::mapped_type 
class Compare = less<Key>                   //map::key_compare           
class Alloc = allocator<pair<const Key,T> > //map::allocator_type
⭕std::pair<const Key, T>
  1. pair<const Key, T> 是 C++ STL 中的一个模板类,用于表示一组键值对,其中键类型为 const Key,值类型为 T。它是由头文件 <utility> 提供的。

  2. std::pair 是一个简单的容器类,用于保存两个值,并为这两个值提供了相应的访问方式。它有两个成员变量 firstsecond,分别用于存储第一个值和第二个值。

  3. std::pair<const Key, T> 中,键是一个 const 类型,即不可修改。这意味着一旦设置了键的值,就无法再更改它。这样设计是为了确保 std::map 等关联容器的键的稳定性和排序规则。

  4. std::pair<const Key, T> 常常用来表示 std::map 或其他类似容器中的一个元素。每个元素由一个键和一个值组成,键的类型是 const Key,即不可修改,值的类型是 T

可以通过以下方式访问 pair<const Key, T> 对象中的键和值:

  • pair.first:表示键的成员变量,类型为 const Key
  • pair.second:表示值的成员变量,类型为 T

- map的构造函数

  1. 默认构造函数:

    std::map<Key, T> myMap;
    

    创建一个空的 std::map 对象,其中键的类型为 Key,值的类型为 T

  2. 区间构造函数:

    template< class InputIt >
    std::map( InputIt first, InputIt last,const Compare& comp = Compare(),const Allocator& alloc = Allocator() );
    

    使用范围 [first, last) 内的元素创建一个新的 std::map 对象。firstlast 是输入迭代器,用于指定范围。元素的类型必须可以隐式转换为 std::pair<const Key, T>。可选地,可以提供一个比较函数对象 comp 和一个分配器 alloc

  3. 拷贝构造函数:

    std::map( const std::map& other );
    

    使用另一个 std::map 对象 other 中的所有元素创建一个新的 std::map 对象。创建的对象将拥有与 other 相同的键值对。

  4. 移动构造函数:

    std::map( std::map&& other ) noexcept;
    

    使用另一个 std::map 对象 other 中的所有元素创建一个新的 std::map 对象。创建的对象将拥有 other 的键值对,并且 other 将被清空。

- map的迭代器

  1. 正向迭代器 (iterator) 和常量正向迭代器 (const_iterator):

    • 用途:可用于遍历 std::map 容器,并且可以修改或访问键值对。
    • 示例用法:
      std::map<Key, Value> myMap;
      for (auto iter = myMap.begin(); iter != myMap.end(); ++iter) {const Key& key = iter->first;     // 键Value& value = iter->second;      // 值// 进行操作或访问
      }
      
  2. 反向迭代器 (reverse_iterator) 和常量反向迭代器 (const_reverse_iterator):

    • 用途:可用于以相反的顺序遍历 std::map 容器,并且可以修改或访问键值对。
    • 示例用法:
      std::map<Key, Value> myMap;
      for (auto rIter = myMap.rbegin(); rIter != myMap.rend(); ++rIter) {const Key& key = rIter->first;    // 键Value& value = rIter->second;     // 值// 进行操作或访问
      }
      
  3. 常量迭代器 (const_iterator) 和常量反向迭代器 (const_reverse_iterator):

    • 用途:用于遍历 std::map 容器,但不能修改键值对。仅适用于 const std::map 对象。
    • 示例用法:
      const std::map<Key, Value> myMap;
      for (auto cIter = myMap.begin(); cIter != myMap.end(); ++cIter) {const Key& key = cIter->first;     // 键const Value& value = cIter->second; // 值// 进行访问操作
      }
      

总结成一个表格如下:

函数功能介绍
begin()返回一个迭代器,指向容器中的第一个元素
end()返回一个迭代器,指向容器中最后一个元素的下一个位置
cbegin()cend()与begin和end意义相同,但cbegin和cend所指向的元素不能修改
rbegin()返回一个反向迭代器,指向容器中最后一个元素的下一个位置
rend()返回一个反向迭代器,指向容器中第一个元素
crbegin()返回一个常量反向迭代器,指向容器中最后一个元素的下一个位置
crend()返回一个常量反向迭代器,指向容器中第一个元素

- map的容量与元素访问函数

🍁容量函数
  1. empty():返回一个布尔值,表示 std::map 是否为空。如果为空,则返回 true;否则,返回 false

    std::map<Key, Value> myMap;
    if (myMap.empty()) {// map为空
    }
    
  2. size():返回 std::map 容器中键值对的数量。

    std::map<Key, Value> myMap;
    std::size_t count = myMap.size();
    
🍁元素访问函数
  1. operator[]:使用指定的键获取或设置相应的值。如果键不存在,会插入一个新的键值对

    std::map<Key, Value> myMap;
    myMap[key] = value;        // 设置键为key的值为value
    Value val = myMap[key];    // 获取键为key的值
    
  2. at():根据指定的键获取相应的值,如果键不存在,会抛出 std::out_of_range 异常

    std::map<Key, Value> myMap;
    Value val = myMap.at(key);  // 获取键为key的值
    
  3. insert():插入一个新的键值对到 std::map 容器中。

    std::map<Key, Value> myMap;
    myMap.insert(std::make_pair(key, value));  // 插入键值对(key, value)
    
  4. erase():根据指定的键删除相应的键值对。

    std::map<Key, Value> myMap;
    myMap.erase(key);   // 删除键为key的键值对
    

🚨🚨注意:对于operator[]来说如果键不存在,会插入一个新的键值对at()函数如果键不存在,会抛出 std::out_of_range 异常

3. map的所有函数(表)

函数用法功能解释
empty()返回一个布尔值,表示 std::map 是否为空。如果为空,则返回 true;否则,返回 false
size()返回 std::map 容器中键值对的数量。
operator[]使用指定的键获取或设置相应的值。如果键不存在,会插入一个新的键值对。
at()根据指定的键获取相应的值,如果键不存在,会抛出 std::out_of_range 异常。
insert()插入一个新的键值对到 std::map 容器中。
erase()根据指定的键删除相应的键值对。
find()根据指定的键查找相应的键值对,并返回指向该键值对的迭代器。如果键不存在,则返回指向末尾的迭代器。
count()返回指定键的数量。由于 std::map 中的键是唯一的,所以返回值要么是 0(键不存在),要么是 1(键存在)。
begin()返回一个迭代器,指向 std::map 中第一个键值对。
end()返回一个迭代器,指向 std::map 中最后一个键值对的下一个位置。
rbegin()返回一个反向迭代器,指向 std::map 中最后一个键值对。
rend()返回一个反向迭代器,指向 std::map 中第一个键值对的前一个位置。
lower_bound()返回一个迭代器,指向大于等于给定键的第一个键值对。
upper_bound()返回一个迭代器,指向大于给定键的第一个键值对。
equal_range()返回一个 std::pair,其中包含两个迭代器:第一个迭代器指向大于等于给定键的第一个键值对,第二个迭代器指向大于给定键的第一个键值对。
clear()清空 std::map 容器中的所有键值对。

三、std::multimap

1. std::multimap简介

⭕ 官方文档 > 链接

在这里插入图片描述
std::multimap 是 C++ 标准库中的关联容器之一,它提供了对键值对的有序存储和访问能力,并且允许多个元素具有相同的键。

std::multimap 的特点如下:

  1. 存储重复键:std::multimap 允许多个元素具有相同的键。这意味着你可以在 std::multimap 中存储重复的键值对,每个键对应一个值。
  2. 排序:std::multimap 内部使用红黑树(Red-Black Tree)实现,可以保持元素的有序性。默认情况下,元素按照键的升序排序,但你也可以通过自定义的比较函数或比较运算符来指定排序规则。
  3. 插入和访问:向 std::multimap 中插入新元素时,按照键的顺序插入即可,不需要进行键的比较和查找操作。访问元素时,可以使用迭代器进行遍历和访问,也可以使用键进行范围查找。
  4. 动态大小:std::multimap 是动态大小的容器,它会根据元素的插入和删除自动调整自身的大小。

使用 std::multimap 可以方便地处理具有相同键的元素,例如在一个电话簿中存储多个人的联系电话,或者在一个日程安排中存储多个事件的时间。它提供了高效的键值对的插入、访问和搜索操作,并且可以根据指定的排序规则自动对元素进行排序。

🔴在使用上面与std::map的使用方法以及函数类型都一样,这里我就不再过多的赘述了。(详细的说明可以看官方文档的介绍)

四、std::map与std::multimap的比较

  • 相同点:

    1. 存储键值对:std::mapstd::multimap 都用于存储键值对,并提供了对键值对的有序存储和访问能力。
    2. 基于红黑树:std::mapstd::multimap 在内部实现上都使用了红黑树(Red-Black Tree),以保持元素的有序性。
    3. 迭代器支持:它们都提供了迭代器的支持,可以使用迭代器进行遍历、访问和修改容器中的元素。
  • 不同点:

    1. 唯一性:最主要的区别在于键的唯一性。std::map 中的键是唯一的,每个键只能对应一个值,如果插入具有相同键的元素,则会替换原有键对应的值。而 std::multimap 允许多个元素具有相同的键,因此可以在 std::multimap 中存储重复的键值对。
    2. 插入和查找:由于 std::map 中的键是唯一的,插入新元素时要进行键的比较和查找,以保持键的唯一性。这会导致插入和查找的时间复杂度是对数级别的。而 std::multimap 允许重复的键,因此插入新元素时只需按照键的顺序插入即可,插入的时间复杂度为常数级别。
    3. 迭代器范围:对于 std::map,每个键只有一个对应的值,因此迭代器范围是唯一的。而对于 std::multimap,由于允许重复的键,因此迭代器范围可以包含多个具有相同键的元素。

🚨综上所述,选择使用 std::map 还是 std::multimap 取决于你的需求和对键的唯一性的要求。如果需要存储唯一的键值对,可以选择 std::map,如果允许并且需要存储重复的键值对,可以选择 std::multimap

温馨提示

感谢您对博主文章的关注与支持!另外,我计划在未来的更新中持续探讨与本文相关的内容,会为您带来更多关于C++以及编程技术问题的深入解析、应用案例和趣味玩法等。请继续关注博主的更新,不要错过任何精彩内容!

再次感谢您的支持和关注。期待与您建立更紧密的互动,共同探索C++、算法和编程的奥秘。祝您生活愉快,排便顺畅!
在这里插入图片描述

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

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

相关文章

OpenAI ChatGPT API 文档之 Embedding

译者注&#xff1a; Embedding 直接翻译为嵌入似乎不太恰当&#xff0c;于是问了一下 ChatGPT&#xff0c;它的回复如下&#xff1a; 在自然语言处理和机器学习领域&#xff0c;"embeddings" 是指将单词、短语或文本转换成连续向量空间的过程。这个向量空间通常被称…

数字孪生:降低现代船舶水声设备研制风险与成本的关键要素

声波是海洋中唯一能够有效传递远距离信息的载体&#xff0c;1000Hz的声波在海水中的每公里吸收衰减仅为0.067分贝&#xff0c;而在陆地上大显神通的电磁波由于受到海水高介电常数和高导电率的影响&#xff0c;因传播衰减量太大而无法通信。 声波在海洋中的传播也并非一帆风顺。…

Python绘图系统22:实现系统菜单

文章目录 文件菜单子部件开关 Python绘图系统&#xff1a; 前置源码&#xff1a; Python打造动态绘图系统&#x1f4c8;一 三维绘图系统 &#x1f4c8;二 多图绘制系统&#x1f4c8;三 坐 标 轴 定 制&#x1f4c8;四 定制绘图风格 &#x1f4c8;五 数据生成导入&#x1f4c8;…

人工智能安全-2-非平衡数据处理(2)

5 算法层面 代价敏感&#xff1a;设置损失函数的权重&#xff0c;使得少数类判别错误的损失大于多数类判别错误的损失&#xff1b; 单类分类器方法&#xff1a;仅对少数类进行训练&#xff0c;例如运用SVM算法&#xff1b; 集成学习方法&#xff1a;即多个分类器&#xff0c;然…

【OpenSSL】单向散列函数

什么是单向散列函数 任意长度数据生成固定长度是散列快速计算消息变化散列变化单向不可逆&#xff0c;抗碰撞 应用场景 文件完整性口令加密消息认证伪随机数配合非对称加密做数字签名比特币工作量证明 单向hash抗碰撞 弱抗碰撞 给定X和hash值的情况下&#xff0c;找到另外…

怎么使用 Go 语言操作 Apache Doris

Apache Doris 是一个基于 MPP 架构的高性能、实时的分析型数据库&#xff0c;以极速易用的特点被人们所熟知&#xff0c;仅需亚秒级响应时间即可返回海量数据下的查询结果&#xff0c;不仅可以支持高并发的点查询场景&#xff0c;也能支持高吞吐的复杂分析场景。基于此&#xf…

buuctf-[网鼎杯 2020 朱雀组]phpweb

1.打开网站&#xff0c;吓我一跳 2.查看源代码&#xff0c;主要看到timezone&#xff0c;然后这个页面是五秒就会刷新一次 一开始去搜了这个&#xff0c;但是没什么用 3.使用bp抓包 会发现有两个参数&#xff0c;应该是用func来执行p 4.修改func和p file_get_contents&#…

7.网络原理之TCP_IP(上)

文章目录 1.网络基础1.1认识IP地址1.2子网掩码1.3认识MAC地址1.4一跳一跳的网络数据传输1.5总结IP地址和MAC地址1.6网络设备及相关技术1.6.1集线器&#xff1a;转发所有端口1.6.2交换机&#xff1a;MAC地址转换表转发对应端口1.6.3主机&#xff1a;网络分层从上到下封装1.6.4主…

HTTP 与 HTTPS

文章目录 HTTP协议一、什么是HTTP协议二、HTTP 协议通信过程三、URL什么是URI 四、HTTP报文1、请求报文&#xff08;1&#xff09;请求报文结构 2、响应报文&#xff08;1&#xff09;响应报文结构 五、HTTP请求方式1、GET&#xff1a;获取资源2、POST&#xff1a;提交数据增加…

巨人互动|Facebook海外户Facebook内容的类型

随着人们日益依赖的社交媒体来进行信息获取与交流&#xff0c;Facebook作为全球最大的社交媒体平台之一&#xff0c;那么Facebook的内容都有哪些类型呢&#xff1f;下面小编来讲讲吧&#xff01; 1、实时发生的事 我们需要实时了解时事动态&#xff0c;这样可以使用户对品牌发…

三个要点,掌握Spring Boot单元测试

单元测试是软件开发中不可或缺的重要环节&#xff0c;它用于验证软件中最小可测试单元的准确性。结合运用Spring Boot、JUnit、Mockito和分层架构&#xff0c;开发人员可以更便捷地编写可靠、可测试且高质量的单元测试代码&#xff0c;确保软件的正确性和质量。 一、介绍 本文…

AWS SAA知识点整理(作成中)

共通 一些信息已经更新了&#xff0c;但参考题的答案还是旧的。 比如&#xff1a; S3的最大读写性能已经提高到 3,500 PUT/COPY/POST/DELETE or 5,500 GET/HEAD requests per second 并且不再要求使用random prefix 题目中有时候会让选择Not violation 不合适的一项&#xff…

mybatisPlus代码生成器

一、添加和mybatisPlus相关的依赖 二、创建代码生成器类 package com.example.mybatisplus_generator.generator;import com.baomidou.mybatisplus.generator.FastAutoGenerator; import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;public class Co…

智算创新,美格智能助力智慧支付加速发展

9月21日&#xff0c;以“智算引领创新未来”为主题的紫光展锐2023泛物联网终端生态论坛在深圳举行。作为紫光展锐重要战略合作伙伴&#xff0c;美格智能标准模组产品线总经理郭强华、高级产品总监刘伟鹏受邀出席论坛。美格智能基于紫光展锐5G、4G、智能SoC、Cat.1 bis等芯片平台…

SpringCloud 简单的了解

什么是SpringCloud ? 基于 Spring Boot 的 Spring 集成应用程序&#xff0c;它利用 Spring Boot 的开发便利性简化了分布式系统的开发&#xff0c;提供与外部系统的集成。 如服务注册与发现、配置中心、负载均衡、断路器、消息总线、数据监控等&#xff1b;换句话说&#xff…

Zilliz@阿里云:大模型时代下Milvus Cloud向量数据库处理非结构化数据的最佳实践

大模型时代下的数据存储与分析该如何处理?有没有已经落地的应用实践? 为探讨这些问题,近日,阿里云联合 Zilliz 和 Doris 举办了一场以《大模型时代下的数据存储与分析》为主题的技术沙龙,其中,阿里云对象存储 OSS 上拥有海量的非结构化数据,Milvus(Zilliz)作为全球最有…

飞致云开源社区月度动态报告(2023年9月)

自2023年6月起&#xff0c;中国领先的开源软件公司FIT2CLOUD飞致云以月度为单位发布《飞致云开源社区月度动态报告》&#xff0c;旨在向广大社区用户同步飞致云旗下系列开源软件的发展情况&#xff0c;以及当月主要的产品新版本发布、社区运营成果等相关信息。 飞致云开源大屏…

django_auth_ldap登录权限

用户登录权限分为三种&#xff0c;通过is_active,is_staff,is_superuser标识。可以对组赋予对应的权限。 设定active组、staff组和superuser组分别对应三种权限。在不同组权限下的登录情况如下&#xff1a; 当用户不属于任何一组&#xff1a; 登录失败&#xff0c;提示如图&a…

MonkeyRunner测试步骤

首先把安卓SDK的 环境变量给配置好&#xff0c;这里就不再多解释&#xff0c;自己google 然后将自己的安卓设备打开调试模式&#xff0c;USB连接至电脑&#xff0c;运行CMD,输入命令adb devices 查看你的安卓设备的ID&#xff08;ID后面写程序会调用&#xff09;&#xff0c;…

容器启动报错

容器启动报错 docker: Error response from daemon: driver failed programming external connectivity on endpoint XXX 如下&#xff1a; 据百度&#xff1a; 在docker启动后在&#xff0c;再对防火墙firewalld进行操作&#xff0c;就会发生上述报错 详细原因&#xff1a…