std::map

news2024/10/5 4:41:22

std::map是C++标准库中的一个关联容器,它基于红黑树实现,用于存储键值对。与标准数组或向量不同,std::map允许你根据键来快速检索、插入和删除元素。正如std::vector包含在< vector >头文件中,std::map包含在< map >头文件中。

std::map的特性:

  • 键值对存储:每个元素是一个键值对,键用于索引,值存储数据
  • 自动排序:元素根据键的顺序自动排序,通常是按照键的升序排列
  • 唯一键:每个键在std::map中都是唯一的,不会存在重复的键;如果插入了相同的键,则新的键值对会覆盖原来的键值对
  • 模板类:std::map是一个模板类,可以存储任何可比较类型的键和值

在红黑树中,每个节点包含一个键值对和指向左右子节点的指针。元素按照键的大小顺序排列,因此红黑树的节点是按照键的大小顺序排列的。当执行插入、删除或查找操作时,红黑树会根据节点的键进行自平衡操作,以保持树的平衡性。这些自平衡操作包括颜色翻转、左旋和右旋等,通过这些操作,红黑树可以保持平衡,同时保持较高的性能。

std::map提供了一系列成员函数来操作和管理键值对:

  • 构造函数

    • map():默认构造函数,创建一个空的std::map对象

    • map(InputIterator first, InputIterator last):根据指定范围的元素构造map

    • map(const map& other):复制构造函数,创建一个新的map,包含另一个map的所有元素

      std::map<std::string, int> my_map;  // 创建一个map,存储字符串键和整数值的键值对
      
      my_map.insert({ "B", 1 });  // 添加一个键值对
      my_map.insert({ "D", 2 });  // 添加一个键值对
      my_map.insert(std::make_pair("C", 3));  // 添加一个键值对
      my_map.insert(std::make_pair("A", 4));  // 添加一个键值对
      for (auto value : my_map) {
          std::cout << value.first << ": " << value.second << std::endl;  // A: 4  B: 1  C: 3  D: 2
      }
      
      std::map<std::string, int> new_map1(my_map);  // 通过拷贝构造创建新的map对象,深拷贝
      std::cout << my_map.size() << std::endl;  // 4
      std::cout << new_map1.size() << std::endl;  // 4
      
      std::map<std::string, int> new_map2(std::move(my_map));  // 通过移动构造创建新的map对象
      std::cout << my_map.size() << std::endl;  // 0
      std::cout << new_map2.size() << std::endl;  // 4
      
  • 赋值操作

    • 赋值运行符 =:将一个map的内容复制给另一个map

    • swap(std::map& other):交换两个map的内容

      std::map<std::string, int> my_map = { {"B", 1}, {"A", 2}, {"C", 3}};  // 创建一个map,并进行初始化
      
      std::map<std::string, int> new_map = my_map;  // 创建新的map对象,并将my_map的内容复制给new_map
      for (auto value : new_map) {
          std::cout << value.first << ": " << value.second << std::endl;  // A: 2  B: 1  C: 3
      }
      
      std::map<std::string, int> other_map{{"ABC", 1}, {"DEF", 2}};  // 创建新的map对象,并进行初始化
      my_map.swap(other_map);  // 交换两个map的内容
      for (auto value : my_map) {
          std::cout << value.first << ": " << value.second << std::endl;  // ABC: 1  DEF: 2
      }
      for (auto value : other_map) {
          std::cout << value.first << ": " << value.second << std::endl;  // A: 2  B: 1  C: 3
      }
      
  • 访问元素

    • operator[]:通过键访问元素,如果键不存在,则插入该键并分配新的值

    • at(const key_type& key):通过键访问元素,带边界检查

      std::map<std::string, int> my_map = { {"B", 1}, {"A", 2}, {"C", 3}};  // 创建一个map,并进行初始化
      
      my_map["D"] = 5;  // 添加一个键值对
      my_map["E"] = 4;  // 添加一个键值对
      for (auto value : my_map) {
          std::cout << value.first << ": " << value.second << std::endl;  // A: 2  B: 1  C: 3  D: 5  E: 4
      }
      
      std::cout << my_map["B"] << std::endl;  // 1
      std::cout << my_map.at("B") << std::endl;  // 1
      std::cout << my_map["F"] << std::endl;  // 0;如果map中没有相应的键,则会将其插入,并将其对应的值赋为0
      
  • 插入元素

    • insert(const value_type& value):插入一个键值对

    • emplace(Args&&… args):在map中就地构造一个新元素

      std::map<std::string, int> my_map{{"B", 1}, {"A", 2}};  // 创建一个map,并进行初始化
      
      my_map.insert({ "D", 1 });  // 添加一个键值对
      my_map.emplace(std::make_pair("C", 2));  // 就地构造一个元素
      for (auto value : my_map) {
          std::cout << value.first << ": " << value.second << std::endl;  // A: 2  B: 1  C: 2  D: 1
      }
      
  • 删除元素

    • erase(const key_type& key):删除指定键对应的元素

    • clear():清空map中的所有元素

      std::map<std::string, int> my_map = { {"B", 1}, {"A", 2}, {"C", 3}};  // 创建一个map,并进行初始化
      
      my_map.erase("A");  // 删除键为"A"的元素
      for (auto value : my_map) {
          std::cout << value.first << ": " << value.second << std::endl;  // B: 1  C: 3
      }
      
      my_map.clear();  // 清空map中的所有元素
      std::cout << my_map.size() << std::endl;  // 0
      
  • 查找元素

    • find(const key_type& key):查找指定键的元素,返回指向该元素的迭代器

    • count(const key_type& key):返回指定键在map中出现的次数(总是0或1)

      std::map<std::string, int> my_map = { {"B", 1}, {"A", 2}, {"C", 3} };  // 创建一个map,并进行初始化
      
      std::cout << my_map.count("A") << std::endl;  // 1;map中存在该键,结果为1
      std::cout << my_map.count("D") << std::endl;  // 0;map中不存在该键,结果为0
      
  • 容量

    • empty():检查map是否为空

    • size():返回map中元素的数量

    • max_size():返回map能容纳的最大元素数量

      std::map<std::string, int> my_map;  // 创建一个map,存储字符串键和整数值的键值对
      
      my_map.insert({ "B", 1 });  // 添加一个键值对
      my_map.insert({ "D", 2 });  // 添加一个键值对
      my_map.insert(std::make_pair("C", 3));  // 添加一个键值对
      my_map.insert(std::make_pair("A", 4));  // 添加一个键值对
      
      bool is_empty = my_map.empty();  // 判断map是否为空,如果为空,返回1;如果不为空,返回0
      std::cout << is_empty << std::endl;  // 0
      
      std::cout << my_map.size() << std::endl;  // 4
      std::cout << my_map.max_size() << std::endl;  // 230584300921369395,能容纳的最大元素数量
      
  • 迭代器

    • begin():返回指向第一个元素的迭代器
    • end():返回指向尾后一个位置的迭代器
    • rbegin():返回指向最后一个元素的逆向迭代器
    • rend():返回指向首个元素前一个位置的逆向迭代器

std::map的性能受到多种因素的影响,包括但不限于以下几点:

  • 底层数据结构:std::map基于红黑树实现,确保了在查找、插入和删除操作上有较好的平衡性能
  • 插入和删除操作:由于std::map是有序的关联容器,插入和删除操作可能需要重新平衡底层的红黑树,因此插入和删除元素的性能可能略低于无序容器,例如std::unordered_map
  • 查找操作:由于底层使用了红黑树,std::map的查找操作的时间复杂度为O(logn),其中n是容器中元素的数量,这使得在大型数据集上查找效率较高
  • 内存占用:红黑树作为底层数据结构,每个节点需要存储额外的指针和颜色信息,因此std::map相比于一些无序容器可能会消耗更多的内存
  • 迭代器稳定性:std::map的迭代器在插入和删除操作后仍然有效,这意味着不会因为插入或删除元素而使现有的迭代器失效

std::map在大多数情况下提供了较好的性能和稳定性,特别适用于需要有序存储和高效查找的场景。然而在某些特定情况下,例如需要快速的插入和删除操作,并且不需要元素的顺序关系时,可能会有更合适的选择。

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

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

相关文章

HBuilderX连接MuMu模拟器最简单的方法

1、在MuMu官网下载MuMu模拟器官网_安卓12模拟器_网易手游模拟器 跟随步骤安装 2、安装后打开MuMu多开器&#xff0c;查看ADB端口号 或者启动MuMu模拟器在问题诊断中查看 3、在HBuilder中配置模拟器端口号和adb路径 4.配置环境变量 5、adbl连接端口 打开cmd运行以下命令 adb …

系统架构设计师-下午案例题(2022年下半年)

1.试题-(共25分):阅读以下关于软件架构设计与评估的叙述在答题纸上回答问题1和问题2。 【说明】某电子商务公司拟升级其会员与促销管理系统&#xff0c;向用户提供个性化服务&#xff0c;提高用户的粘性。在项目立项之初&#xff0c;公司领导层一致认为本次升级的主要目标是提…

随笔(四)——代码优化

文章目录 前言1.原本代码2.新增逻辑3.优化逻辑 前言 原逻辑&#xff1a;后端data数据中返回数组&#xff0c;数组中有两个对象&#xff0c;一个是属性指标&#xff0c;一个是应用指标&#xff0c;根据这两个指标展示不同的多选框 1.原本代码 getIndicatorRange(indexReportLi…

逗比大神(ToyoDAdoubi)的ShadowsocksR/SSR一键搭建脚本

逗比大神(ToyoDAdoubi)的ShadowsocksR/SSR一键搭建脚本&#xff08;推荐&#xff09; 我推荐新手小白用户使用逗比大神(ToyoDAdoubi)的SSR一键搭建脚本&#xff0c;因为全中文界面&#xff0c;操作更加简单方便。 此一键安装脚本支持 CentOS 6、Debian 7、Ubuntu 12 及以上系…

10.4学习

1.Transactional 注意事项&#xff1a; ①事务函数中不要处理耗时任务&#xff0c;会导致长期占有数据库连接。 ②事务函数中不要处理无关业务&#xff0c;防止产生异常导致事务回滚。 ●事务传播属性 ①REQUIRED&#xff08;默认属性&#xff09; 如果存在一个事务&#…

ROS基础入门——实操教程

ROS基础入门——实操教程 前言 本教程实操为主&#xff0c;少说书。可供参考的文档中详细的记录了ROS的实操和理论&#xff0c;只是过于详细繁杂了&#xff0c;看得脑壳疼&#xff0c;于是做了这个笔记。 Ruby Rose&#xff0c;放在这里相当合理 本文初编辑于2024年10月4日 C…

云原生(四十五) | ECS服务器项目部署实战

文章目录 ECS服务器项目部署实战 一、ECS服务器项目部署说明 二、下载WordPress 三、部署WordPress需要哪些应用 ECS服务器项目部署实战 一、ECS服务器项目部署说明 案例&#xff1a;为了让大家更好的理解ECS服务器的使用场景&#xff0c;我们通过一个比较经典的WordPres…

红日靶机(三)笔记

VulnStack-红日靶机三 概述 相较于前边两个靶场环境&#xff0c;靶场三的难度还是稍难一点&#xff0c;有很多兔子洞&#xff0c;这就考验我们对已有信息的取舍和试错&#xff0c;以及对渗透测试优先级的判断。涉及到对数据库操作的试错&#xff0c;对 joomla 框架 cve 的快速…

vSAN01:vSAN简介、安装、磁盘组、内部架构与调用关系

目录 传统的共享存储vSAN存储OSA的系统要求vSAN安装vSAN集群vSAN skyline healthvSAN与HA磁盘组混合磁盘架构全闪磁盘架构 vSAN对象vSAN内部架构 传统的共享存储 通过隔离的存储网络使得不同的ESXi主机访问独立的存储设备。需要前期投入较高的资金单独采购存储、网络可以单独规…

OAuth2.0 设备授权流程

OAuth2.0设备授权流程&#xff08;Device Authorization Grant&#xff09;是一种为缺乏输入能力的设备&#xff08;例如智能电视、游戏机、物联网设备等&#xff09;设计的授权模式。这些设备通常不具备复杂的键盘或指定输入方式&#xff0c;无法直接进行OAuth2.0标准的交互授…

8c语言基础文件

关于文件你必须了解的一些基本概念 什么是文件&#xff1f; 文件是计算机文件&#xff0c;属于文件的一种&#xff0c;与普通文件的载体不同&#xff0c;计算机文件是以计算机硬盘为载体存储在计算机上的信息集合。 在程序设计中&#xff0c;我们一般关注的文件有两类&#x…

【C++】空指针和野指针

文章目录 1.空指针2.野指针总结 1.空指针 概念&#xff1a;指针变量指向内存中编号为0的空间。 用途&#xff1a;初始化指针变量。 注意&#xff1a;空指针指向的内存是不可以访问的。 示例&#xff1a; int main(){//指针变量p指向内存地址编号为0的空间int *PNULL&#…

从零开始学cv-15:图像分割

文章目录 前言一、全局阈值分割&#xff1a;二、自适应阈值分割&#xff1a;三、分水岭算法&#xff1a; 前言 在当代计算机视觉领域&#xff0c;图像分割技术扮演着至关重要的角色&#xff0c;它为图像理解、目标识别和场景解析等高级视觉任务提供了基础。OpenCV&#xff0c;…

Redis:hash类型

Redis&#xff1a;hash类型 hash命令设置与读取HSETHGETHMGET 哈希操作HEXISTSHDELHKEYSHVALSHGETALLHLENHSETNXHINCRBYHINCRBYFLOAT 内部编码ziplisthashtable 目前主流的编程语言中&#xff0c;几乎都提供了哈希表相关的容器&#xff0c;Redis自然也会支持对应的内容&#xf…

李宏毅深度学习-循环神经网络RNN

Recurrent Neural Network 这个问题可以使用一个前馈神经网络&#xff08;feedforward neural network&#xff09;来解&#xff0c;如图5.2 所示&#xff0c; 输入是一个单词&#xff0c;把“上海”变成一个向量&#xff0c;“丢”到这个神经网络里面。输入是一个单词&#x…

平衡二叉搜索树---java---黑马

平衡二叉搜索树 AVL树的实现 二叉搜索树在插入和删除时&#xff0c;节点可能发生失衡&#xff1b;如果在插入和删除时通过旋转&#xff0c;始终让二叉搜索树保持平衡&#xff0c;称之为平衡二叉搜索树&#xff1b;AVL树是自平衡二叉搜索树的实现之一 LL - 失衡节点(图中5红…

项目-坦克大战学习笔记-地图完善

之前我们详细讲解了怎么在地图上绘制墙&#xff0c;这次我们来完善整个地图&#xff0c; 地图的静态物体构成分为可破坏的墙体&#xff0c;不可破坏的铁块&#xff0c;以及最终boos 那我们为了方便存储将三个对象分开放为3个列表 private static List<gudin> walllist…

vscode有问题

开始给我报错&#xff0c;说命名不规范 然后我就改&#xff0c;改了好几遍之后还是报错。问了ai&#xff0c;也用它的方法改了&#xff0c;还是报错。。。 然后关掉vscode&#xff0c;重启&#xff0c;&#xff0c;&#xff0c;&#xff0c;&#xff0c;&#xff0c;运行成功

【算法系列-链表】删除链表的倒数第N个结点

【算法系列-链表】删除链表的倒数第N个结点 文章目录 【算法系列-链表】删除链表的倒数第N个结点1. 算法分析&#x1f6f8;2. 模拟解决问题2.1 思路分析&#x1f3af;2.2 代码示例&#x1f330; 3. 双指针(快慢指针)解决问题3.1 思路分析&#x1f3af;3.2 代码示例&#x1f330…

Web-Machine-N7解题过程

1.主机探测 arp-scan -lnmap -sn 192.168.1.0/24sudo netdiscover -r 192.168.1.0/24masscan -p0-65535 192.168.1.0/24 2.端口扫描 nmap -A -sC -sT -sV 192.168.1.188 --min-rate 10000 &#xff08;简略扫描&#xff09;nmap -sS 192.168.1.188 -A&#xff1a; 启用操作系…