【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.mzph.cn/bicheng/11196.shtml

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

相关文章

codeforce#939 (div2) 题解

C. Nene’s Magical Matrix 给一个nxn的矩阵&#xff0c;现在你可以执行一个操作&#xff1a;将数字1-n任意排列&#xff0c;并将这个序列覆盖到矩阵的任意一行或列。操作次数小于 2 n 2n 2n&#xff0c;求矩阵中元素和的最大值。 这个题显然存在一种巧妙的构造方法使得矩阵中…

软件设计各个阶段的成果

软件设计各个阶段的成果 1.可行性分析与项目开发计划2.需求分析3.系统设计4.系统测试运行和维护知识 自行整理的软件设计阶段性成果&#xff0c;如有不对的地方&#xff0c;欢迎指正。 1.可行性分析与项目开发计划 可行性分析报告项目开发计划 2.需求分析 软件需求说明书用…

MySql软件安装

1.打开mysql官网网址 MySQL :: Download MySQL Community Server 2.本次针对版本8的图形化界面安装&#xff0c;下载成功后接下来对MySQL进行安装 3.图形化下载后有一个MSI文件 4.我们安装典型即可&#xff0c;选择第一个 5.选择数据库信息存放的路径&#xff0c;我默认放在C盘…

springboot集成SpringIntegration

SpringIntegration的核心 Spring Integration的核心是消息驱动的架构。它提供了一种途径来将应用程序的各个组件&#xff08;例如&#xff1a;系统、服务、应用程序&#xff09;通过消息进行连接&#xff0c;从而实现系统的解耦和灵活性。Spring Integration基于企业集成模式&a…

Python 中字符串列表的排序

&#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ 在 Python 中&#xff0c;列表中字符串元素的排序可以通过多种方式实现&#xff0c;主要依赖于 sort() 方法和 sorted() 函数。这两种方式都可以有效地对字符串列表进行排序&#xff0c;但它们在使用方…

十个简单的Python类的例子

十个简单的Python类的例子 涵盖了基本的类概念、实例属性、方法及一些高级应用。 内容从浅入深。 例子 1&#xff1a;定义一个简单的类 class Dog:def __init__(self, name):self.name namedef bark(self):return "Woof!"# 使用类 my_dog Dog("Buddy")…

如何解决pycharm在HTML文件中注释快捷键出错的问题(HTML注释规则出错)

文章目录 💢 问题 💢🏡 演示环境 🏡💯 解决方案 💯⚓️ 相关链接 ⚓️💢 问题 💢 你是否在编程时遇到过这样的烦恼?当你正专注地编写HTML代码,想要快速注释掉某部分内容时,却发现PyCharm的注释快捷键失灵了(没有使用正确的注释格式)。这不仅打断了你的工作…

每日一题10:Pandas:重塑数据-联结

一、每日一题 DataFrame df --------------------- | Column Name | Type | --------------------- | student_id | int | | name | object | | age | int | ---------------------DataFrame df --------------------- | Column Name | Type | --…

Cpython 的使用

前言 Python 程序中一些关键代码不想公开&#xff0c;可以使用 Cpython 来编译&#xff0c;然后正常导入 开始 需要明确一点&#xff0c;CPython 是 Python 的默认和最常用的解释器实现&#xff0c;而 .pyd 文件是一种特定于 Windows 的 Python 动态链接库&#xff08;DLL&a…

Spring Event--踩坑(注意事项)

原文网址&#xff1a;Spring Event--踩坑(注意事项)-CSDN博客 简介 本文介绍Spring的事件的使用注意事项。 Spring Event框架实现了基于事件的发布订阅机制。开发者可以自定义事件&#xff0c;发布事件&#xff0c;Spring 会将该事件广播给监听该事件的监听者。监听者可以实…

linux学习:视频输入+V4L2

目录 V4L2 视频采集流程 代码例子 核心命令字和结构体 VIDIOC_ENUM_FMT VIDIOC_G_FMT / VIDIOC_S_FMT / VIDIOC_TRY_FM VIDIOC_REQBUFS VIDIOC_QUERYBUF VIDIOC_QBUF /VIDIOC_DQBUF VIDIOC_STREAMON / VIDIOC_STREAMOFF V4L2 是 Linux 处理视频的最新标准代码模块&…

Java后端实现对象与文件接收数据(minio测试)

实现思路&#xff1a; 1. 两个接口实现&#xff0c;一个接对象数据(file)&#xff0c;一个接文件数据(json)。 2. json对象(base64String) 实体类信息 &#xff0c;请求体统一接收 3. file, String name ,String password ,String name &#xff0c; Controller层接收 统一…

如何查看PostgreSQL的版本

如何查看PostgreSQL的版本 要查看 PostgreSQL 的版本&#xff0c;有几种不同的方法可以使用&#xff0c;包括通过命令行和 SQL 查询。 1. 使用命令行 如果你有访问到服务器的命令行&#xff0c;并且 PostgreSQL 的命令行工具已经添加到了系统的 PATH 中&#xff0c;你可以非…

[muduo网络库]——muduo库noncopyable(剖析muduo网络库核心部分、设计思想)

接着之前我们[muduo网络库]——muduo库TcpConnection类&#xff08;剖析muduo网络库核心部分、设计思想&#xff09;&#xff0c;我们接下来继续看muduo库中的noncopyable。 这一类比较简单&#xff0c;并且我在另一篇博客里面&#xff0c;也有详细的介绍C 11以及muduo网络库中…

函数指针允许将函数作为参数传递或从函数返回函数

函数指针允许您将函数作为参数传递或从函数返回函数&#xff0c;从而实现灵活的行为和代码重用。它们在 C 编程中具有广泛的应用&#xff0c;包括回调、事件处理和算法选择。了解函数指针及其用法可以帮助您编写更模块化、可扩展和可定制的代码。以下是函数指针的一些实际应用示…

OpenHarmony 实战开发——如何编译OpenHarmony自带APP

概述 OpenHarmony 的主干代码是开源社区的重要学习资源&#xff0c;对于想进行应用开发和熟悉 OpenHarmony 能力的同学主干代码是非常重要的资源&#xff0c;在主干代码的 applications 目录里聚集了很多原生的应用实现&#xff0c;那么如何编译这些代码就是我们这篇文章的主要…

信息系统架构设计方法_1.ADM架构开发方法

1.TOGAF概述 TOGAF&#xff08;The Open Group Architecture Framework&#xff0c;TOGAF&#xff09;是一种开放式企业架构框架标准&#xff0c;它为标准、方法论和企业架构专业人员之间的沟通提供一致性保障。 TOGAF由国际标准权威组织The Open Group制定。The Open Group于1…

[初学rust] 01_简单打印

print println!() 基本使用 直接输出一个字符串 println!("hello world");{} 占位符 println!("{}", "hello world");

Vue3项目打包部署到云服务器的Nginx中

文章目录 一、打包vue3项目二、dist文件夹上传到服务器三、改nginx配置文件Docker安装nginx 一、打包vue3项目 npm run build 二、dist文件夹上传到服务器 将dist文件夹放到docker安装的nginx中的html目录下 三、改nginx配置文件 然后重启nginx【改了配置文件重启nginx才能…

消息中间件Kafka(PHP版本)

小编最近需要用到消息中间件&#xff0c;有需要要复习一下以前的东西&#xff0c;有需要的自取&#xff0c;强调一点&#xff0c;如果真的想了解透彻&#xff0c;一定要动手&#xff0c;脑袋会了不代表就会写了 Kafka是由Scala和Java编写。Kafka是一种高吞吐量的分布式发布订阅…