【C++】STL — map和set的使用详细介绍

前言
本章将继续学习STL中的两个很重要的容器map和set,其底层实现是封装了一个红黑树,我们通过本节来学习和深入了解一下这两大容器。。。
序列式容器: string 、Vector、List 、dequeue
关联式容器:MAP 、SET、nordered_map、unordered_set。
关联式容器也是用来存储数据的,与序列式容器不同的是,其里面存储的是**<key, value>结构的键值对**,在数据检索时比序列式容器效率更高。
除此之外,序列式容器中存储的元素默认都是未经过排序的,而使用关联式容器存储的元素,默认会根据各元素的键值的大小做升序排序。

目录

    • 1. 键值对的引入
    • 2. set的介绍 + 使用
      • 2.1 set的构造
      • 2.2 set的插入
      • 2.2 set的删除
    • 3. Map 的介绍 + 使用
      • 3.1 Map 的构造
      • 3.2 Map 的插入Insert
      • 3.3 利用map统计次数
      • 3.3 Map 遍历方式
      • 3.4 Map总结

1. 键值对的引入

用来表示具有一一对应关系的一种结构,该结构中一般只包含两个成员变量key和value,key代表键值,value表示与key对应的信息.
在这里插入图片描述
它实际是一个类模板,STL库中给出源代码如下:

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

2. set的介绍 + 使用

使用 set 容器,必须引入该头文件#include < set >

  1. Set是按照一定次序存储元素的容器
  2. Set中的元素不能在容器中修改(元素总是const),但是可以从容器中插入或删除它们
  3. 在set中,存放的是Value**(value就是key,类型为T),并且每个value必须是唯一的.**
  4. 在内部,set中的元素总是按照其内部比较对象(类型比较)所指示的特定严格弱排序准则进行排序
  5. Set容器通过key访问单个元素的速度通常比unordered_set容器慢,但它们允许根据顺序对子集进行直接迭代
  6. set在底层是用二叉搜索树(红黑树)实现的。

注意:(与MAP的区别)

  • 与map/multimap不同,set中只放 value,map 中存储的是真正的键值对<key, value>.
  • Set中插入元素时,只需要插入value即可,不需要构造键值对
  • set中的元素不可以重复(因此可以使用set进行去重)
  • 使用set的迭代器遍历set中的元素,可以得到有序序列

2.1 set的构造

在这里插入图片描述

  • T: set中存放元素的类型,实际在底层存储<value, value>的键值对。
  • Compare:set中元素默认按照小于来比较
  • Alloc:set中元素空间的管理方式,使用STL提供的空间配置器管理
#include <set>
void TestSet()
{
// 用数组array中的元素构造set
int array[] = { 1, 3, 5, 7, 9, 2, 4, 6, 8, 0, 1, 3, 5, 7, 9, 2, 4,
6, 8, 0 };
set<int> s(array, array+sizeof(array)/sizeof(array));
cout << s.size() << endl;// 正向打印set中的元素,从打印结果中可以看出:set可去重
for (auto& e : s)
{cout << e << " ";
}
cout << endl;
}
//使用迭代器逆向打印set中的元素
for (auto it = s.rbegin(); it != s.rend(); ++it)
{cout << *it << " ";cout << endl;
}

2.2 set的插入

在这里插入图片描述
set自带的Find()和算法库中的Find()有什么区别

1.set自带的查找是利用了搜索树的特点,查找时间复杂度为〇(logN)
2.如果用算法库中的查找则是通过暴力查找的方式进行的,时间复杂度为〇(N)

2.2 set的删除

在这里插入图片描述

while (cin >> x){set<int>::iterator pos = s.find(x);if (pos != s.end()){s.erase(pos);//迭代器删除cout << "删除" << x << "成功" << endl;}else{cout << x << "不在set中" << endl;}for (auto e : s){cout << e << " ";}cout << endl;}

3. Map 的介绍 + 使用

  • map是关联容器,它按照特定key的次序存储由键值key和值value组合而成的元素。
  • typedef pair<const key, T> value_type
  • 在内部,map中的元素总是按照键值key进行比较排序的.
  • map支持下标访问符,即在[ ]中放入key,就可以找到与key对应的value
  • map通常被实现为二叉搜索树((红黑树))
  • 统计value相同的次数时,使用[ ]操作符,见下面解释

使用 map 容器,必须引入该头文件#include < map >
在这里插入图片描述

  • key: 键值对中key的类型
  • T: 键值对中value的类型
  • Compare:比较器的类型,map中的元素是按照key来比较的,缺省情况下按照小于来比较,一般情况下(内置类型元素)该参数不需要传递,如果无法比较时(自定义类型),需要用户
    自己显式传递比较规则(一般情况下按照函数指针或者仿函数来传递)
  • Alloc:通过空间配置器来申请底层空间,不需要用户传递,除非用户不想使用标准库提供的 空间配置器

3.1 Map 的构造

在这里插入图片描述

int main ()
{std::map<char,int> first;first['a']=10;first['b']=30;first['c']=50;first['d']=70;std::map<char,int> second (first.begin(),first.end());std::map<char,int> third (second);return 0;}

3.2 Map 的插入Insert

在这里插入图片描述

  • map插入的是一对键值对Pair<K ,v>
  • 通过pair的first和second,即可访问到两个值
  • Key_value模型中,修改不能修改key,但是可以修改value在这里插入图片描述

3.3 利用map统计次数

有两种方案:
(1)通过查找来挨个遍历查找统计次数
(2)使用operator [ ]来进行统计次数

1.通过查找来挨个遍历查找统计个数

void test_map2()
{string arr[] = { "苹果", "西瓜", "苹果", "西瓜", "苹果", "苹果","西瓜", "苹果", "香蕉", "苹果", "香蕉" };map<string, int> countMap;for (auto& str : arr){map<string, int>::iterator it = countMap.find(str);if (it != countMap.end()){it->second++;}else{countMap.insert(make_pair(str, 1));}}
}

2.使用operator [ ]来进行统计次数

  • operator[]的参数是key,返回值是value的引用
  • operator[]都有随机访问的意思,这里的方括号已经没有了随机访问的意思
map<string,int> countMap;
for(auto&str:arr)
{//1.str不在countMap中,插入pair(str,int()),然后再对返回次数++;//2. str在countMap中,返回value(次数)的引用,次数++countMap[str]++;
}

对operator [ ]的讲解:

  • operator[]兼顾了两个功能:插入 + 修改
  • Map中有这个key,返回value的引用(查找、修改value)
  • Map中没有这个key,会插入一个pair(key,v());返回value的引用。(插入+修改)

模拟operator [ ]的实现代码:

v& operator[](const K&key)
{pair<iterator,bool> ret=insert(make_pair(key,v());return ret.first->second;
}
//STl库里面的实现
mapped_type& operator[](const key_type& k)
{return (*((this->insert(make_pair(k,mapped_type()))).first)).second;
}

3.3 Map 遍历方式

在这里插入图片描述

注意

  • sort不能对map进行排序,因为map不是随机迭代器
  • 在元素访问时,有一个与operator[]类似的操作at()(该函数不常用)函数,都是通过key找到与key对应的value然后返回其引用
  • 不同的是:当key不存在时,operator[]用默认value与key构造键值对然后插入,返回该默认value,at()函数直接抛异常。

3.4 Map总结

  • map中的的元素是键值对
  • map中的key是唯一的,并且不能修改
  • 默认按照小于的方式对key进行比较
  • map中的元素如果用迭代器去遍历,可以得到一个有序的序列
  • map的底层为平衡搜索树(红黑树),查找效率比较高 O ( l o g 2 N ) O(log_2 N) O(log2N)
  • 支持[]操作符,operator[]中实际进行插入查找

尾声
看到这里,相信大家对这个C++有了解了。
如果你感觉这篇博客对你有帮助,不要忘了一键三连哦

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

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

相关文章

partially initialized module ‘replicate‘ has no attribute ‘run‘

partially initialized module replicate has no attribute run(most likely due to a circular import) 在包名上停留查看impot 包的地址。 报错原因&#xff1a; 文件重名了&#xff0c;导入了 当前文件 。 修改文件名 即可。

架构设计之学新而知故

缘由 因为一些特殊的机缘&#xff0c;接触到洋葱架构等一些新架构设计概念。 尝试理解了一段时间&#xff0c;就想简单梳理下对它们的理解&#xff0c;以达到学新而知故 &#x1f603; 信息增益 以前计算机专业并不设置通信领域的信息论的专业课程&#xff0c;但是&#xf…

WEB后端复习——javabean与会话cookie、session

JavaBean 是一种符合特定命名约定的 Java 类&#xff0c;它通常用于封装数据。 JavaBean 的主要特点是&#xff1a; 1. 无参构造器&#xff1a;JavaBean 必须有一个公共的&#xff08;public&#xff09;无参构造方法&#xff0c;以便于反射时能够创建对象实例。 2. 属性&…

electron进程间通信

Electron 应用程序的结构非常相似。 作为应用开发者&#xff0c;你将控制两种类型的进程&#xff1a;主进程 和 渲染器进程。 这类似于上文所述的 Chrome 的浏览器和渲染器进程。 主进程 每个 Electron 应用都有一个单一的主进程&#xff0c;作为应用程序的入口点。 主进程在 N…

程序员工作中常见问题,你遇到过几个?

在赛博朋克2077玩后感中&#xff0c;我提到&#xff0c;即便是在严谨的机制下&#xff0c;依然可能出现让人匪夷所思或是贻笑大方的问题。 那么今天&#xff0c;就以后端程序员的视角&#xff0c;盘点下从设计开发到上线的常见问题&#xff0c;看看大家中过几个。 01 设计与开…

【HCIP学习】BGP选路、过滤及属性

一、BGP路由选路原则&#xff08;13条&#xff09; 1、首先丢弃下一跳&#xff08;NEXT_HOP&#xff09;不可达的路由&#xff1b; 2、优选Preferred-value值最大的路由&#xff1b;默认为0&#xff1b; Preferred-value&#xff1a;定义&#xff1a;首选项。 属性值&#…

树莓派点亮FPGA小灯

树莓派点亮FPGA小灯 引言&#xff1a; ​ 本次实验的目的是通过树莓派和FPGA之间的串口通信&#xff0c;控制FPGA开发板上的小灯。实验将展示如何使用树莓派发送特定的字符信号&#xff0c;通过串口传输至FPGA&#xff0c;并在FPGA上实现逻辑解析&#xff0c;以点亮指定的小灯。…

[C#] 使用HttpClient请求https地址报错的解决方案

当使用HttpClient请求HTTPS地址遇到报错时&#xff0c;下面将解析并提供可能的解决方案供参考。 文章目录 异常代码无法定位错误的准确定位错误的 常见错误错误1错误2 解决问题生产环境开发环境 异常代码 首先&#xff0c;需要查看引发异常的代码部分, 无法定位错误的 以下代…

LeetCode 题目 120:三角形最小路径和

作者介绍&#xff1a;10年大厂数据\经营分析经验&#xff0c;现任字节跳动数据部门负责人。 会一些的技术&#xff1a;数据分析、算法、SQL、大数据相关、python&#xff0c;欢迎探讨交流 欢迎加入社区&#xff1a;码上找工作 作者专栏每日更新&#xff1a; LeetCode解锁1000题…

Linux提权--第三方软件MYSQL数据库提权(WEB+本地)

免责声明:本文仅做技术交流与学习,非法搞事后果自负... 目录 靶场镜像: 过程: 手工: 下载mysql udf poc 进行编译. 进入数据库进行UDF导出 下载(上传) 创建do_system函数调用 探针(./LinEnum.sh),查找suid权限. 配合使用find调用执行 工具: 过程: 外连不上? 隧道出…

矿用光缆型号和规格

管道矿用光缆生产厂家&#xff0c;矿用光缆特点是什么&#xff0c;矿用通信光缆 矿用光缆 MGTS光缆的结构是将250 m光纤套入高模量材料制成的松套管中&#xff0c;松套管内填充防水化合物。缆芯的中心是一根金属加强芯&#xff0c;对于某些芯数的光缆来说&#xff0c;金属加强…

K-RTD01和利时FW248中控卡件

K-RTD01和利时FW248中控卡件。 系统概述 的全称为保护工程师站及录波分析后台”是利用现代计算机和网络技术&#xff0c;K-RTD01和利时FW248中控卡件。实时收集变电站运行和故障信息&#xff0c;并通过对变电站的故障信息进行综合分析&#xff0c;K-RTD01和利时FW248中控卡件。…

并发编程实现

一、并行编程 1、Parallel 类 Parallel类是System.Threading.Tasks命名空间中的一个重要类&#xff0c;它提供数据并行和任务并行的高级抽象。 For和ForEach Parallel类下的For和ForEach对应着普通的循环和遍历(普通的for和foreach)&#xff0c;但执行时会尝试在多个线程上…

Python中bisect模块

Python中bisect模块 在Python中&#xff0c;如果我们想维持一个已排序的序列&#xff0c;可以使用内置的bisect模块&#xff0c;例如&#xff1a; import bisect# 用于处理已排序的序列 inter_list [] bisect.insort(inter_list, 3) bisect.insort(inter_list, 2) bisect.in…

python3 Fatal error in launcher: Unable to create process using

python 环境变量 在window系统环境变量 path 中配置 python 的安装目录&#xff0c;目录层级至paython 的安转目录即可。 pip环境变量配置 在path 中增加配置 paython 安装目录下 Scripts 子目录的环境变量。 以上配置完成后&#xff0c;win R 打开命令窗口&#xff0c;输…

汽车商城系统

文章目录 汽车商城系统一、系统演示二、项目介绍三、部分功能截图四、部分代码展示五、底部获取项目源码&#xff08;9.9&#xffe5;带走&#xff09; 汽车商城系统 一、系统演示 汽车商城 二、项目介绍 该汽车商城系统主要分为前台和后台两大功能模块&#xff0c;共包含两种…

利用“AnaTraf“网络流量分析仪轻松诊断和优化网络

网络性能监测和诊断(NPMD)是网络管理和优化的重要环节,准确快速地定位和排除网络故障对于保障业务正常运转至关重要。作为一款专业的网络流量分析设备,AnaTraf网络流量分析仪凭借其强大的流量分析和故障诊断功能,为网络管理者提供了一个高效的网络优化解决方案。 全面掌握网络…

【C++】————类与对象(上)-基础知识

目录 1.面向过程和面向对象初步认识 2.类的引入 3.类的定义 类的两种定义方式&#xff1a; 成员变量命名规则的建议&#xff1a; 4.类的访问限定符及封装 4.1 访问限定符 ​编辑 【面试题】问题&#xff1a;C中struct和class的区别是什么&#xff1f; 4.2 封装 【面试…

ipa 功能包调试,分区算法,覆盖算法测试

参考 wiki 流网络 flow network 解释 相关文章 ipa 分区算法 ipa 分区算法总结&#xff0c;部分算法图解 环境 ubuntu20&#xff0c;ros 版本 noetic 运行测试 按照 readme 提示进行测试&#xff0c;跳过第一个步骤&#xff0c;并不需要 turtlebot3。 执行第三个 launch 报…

【计算机网络篇】数据链路层(10)在物理层扩展以太网

文章目录 &#x1f354;扩展站点与集线器之间的距离&#x1f6f8;扩展共享式以太网的覆盖范围和站点数量 &#x1f354;扩展站点与集线器之间的距离 &#x1f6f8;扩展共享式以太网的覆盖范围和站点数量 以太网集线器一般具有8~32个接口&#xff0c;如果要连接的站点数量超过了…