【C++进阶】五、STL---unordered_set unordered_set的介绍及使用
迪丽瓦拉
2025-05-28 12:48:27
0

目录

一、unordered系列关联式容器

二、unordered_set的介绍及使用

2.1 介绍

2.2 使用

三、unordered_map的介绍及使用

3.1 介绍

3.2 使用


一、unordered系列关联式容器

        在C++98中,STL提供了底层为红黑树结构的一系列关联式容器,在查询时效率可达到 logN,即最差情况下需要比较红黑树的高度次,当树中的节点非常多时,查询效率也不理想

        最好的查询是,进行很少的比较次数就能够将元素找到,因此在C++11中,STL又提供了4个unordered系列的关联式容器,这四个容器与红黑树结构的关联式容器使用方式基本类似,只是其底层结构不同,本文只对 unordered_map 和 unordered_set 进行介绍

        unordered系列容器的底层结构是是哈希桶

二、unordered_set的介绍及使用

2.1 介绍

unordered_set 的文档介绍:

unordered_set - C++ Reference (cplusplus.com)https://legacy.cplusplus.com/reference/unordered_set/unordered_set/?kw=unordered_set

翻译如下:

  1. unordered_set 是不按特定顺序存储唯一元素的容器,允许基于它们的 key 快速检索单个元素
  2. 在 unordered_set 中,元素的值与唯一标识它的 key 同时存在,key 是不可变的,因此,unordered_set 中的元素在容器中不能被修改,但是它可以进行插入和删除
  3. 在内部,unordered_set 中的元素不按任何特定顺序排序,而是根据它们的哈希值插入到相应的桶中,允许直接根据它们的值快速访问单个元素(平均时间复杂度恒定,即常数O(1) )
  4. Unordered_set 容器在通过键访问单个元素时比 set 容器更快,尽管它们在通过元素子集进行范围迭代时通常效率较低
  5. 容器中的迭代器至少是前向迭代器(只支持单向迭代器 ++)

 unordered_set 的模板参数有四个:

  1. 第四个模板参数 class Alloc = allocator 是空间配置器,暂时不用理会
  2. 第三个模板参数 class Hash = hash 是用于指定哈希函数类型,用于将 Key 类型的对象映射为一个无符号整数,这个整数就是哈希表中元素的索引
  3. 第二个模板参数 class Pred = equal_to 是仿函数,用于判断两个 Key 类型的对象是否相等,因为哈希表中可能存在哈希冲突,所以在同一个索引位置上可能会存储多个元素,Pred 就是用来判断这些元素是否相等的
  4. 第一个模板参数 class Key 是指定哈希表中元素的键类型,是键值对中 key 的类型

使用 unordered_set 要包含头文件:

#include 

2.2 使用

先介绍一下 unordered_set 的前四个成员类型

  • key_type 是第一个模板参数,即(Key),value_type 也是第一个模板参数(Key) ,即键值对 pair --> pair
  • hasher 是第二个模板参数,即(Hash)
  • key_equal 是第三个模板参数,即(Pred)

        unordered_set 的使用与 set 非常类似(参考 set 使用即可),但是由于 unordered_set 使用哈希表实现,所以它的效率更高,适用于需要快速查找、插入和删除元素的场景,注意 unordered_set 的迭代器是单向迭代器,只能++

unordered_set 会对插入重复的元素进行去重,即不允许插入相同的值

例如:

#include 
#include 
using namespace std;int main() 
{unordered_set myset = { 1, 2, 3, 2, 4, 3, 5 }; // 插入重复的元素for (auto it = myset.begin(); it != myset.end(); ++it){cout << *it << " ";}return 0;
}

运行结果

三、unordered_map的介绍及使用

3.1 介绍

unordered_map 的文档介绍:

unordered_map - C++ Reference (cplusplus.com)https://legacy.cplusplus.com/reference/unordered_map/unordered_map/?kw=unordered_map

 翻译如下:

  1. unordered_map是存储 键值对的关联式容器,其允许通过keys快速的索引到与其对应的 value
  2. 在unordered_map中,键值通常用于惟一地标识元素,而映射值是一个对象,其内容与此键关联。键和映射值的类型可能不同
  3. 在 unordered_map 内部没有对按照任何特定的顺序排序, 为了能在常数范围内找到key所对应的value,unordered_map 将相同哈希值的键值对放在相同的桶中
  4. unordered_map 容器通过 key 访问单个元素要比 map 快,但它通常在遍历元素子集的范围迭代方面效率较低
  5. unordered_maps实现了直接访问操作符( operator[] ),它允许使用 key作为参数直接访问 value
  6. 它的迭代器至少是前向迭代器(只支持单向迭代器 ++)

 unordered_map 的模板参数有五个: 

  1. 第五个模板参数 class Alloc = allocator 是空间配置器,暂时不用理会
  2. 第四个模板参数 class Hash = hash 是用于指定哈希函数类型,用于将 Key 类型的对象映射为一个无符号整数,这个整数就是哈希表中元素的索引
  3. 第三个模板参数 class Pred = equal_to 是仿函数,用于判断两个 Key 类型的对象是否相等,因为哈希表中可能存在哈希冲突,所以在同一个索引位置上可能会存储多个元素,Pred 就是用来判断这些元素是否相等的
  4. 第二个模板参数 class T 是键值对中 value 的类型
  5. 第一个模板参数 class Key 是键值对中 key 的类型

使用 unordered_map 要包含头文件:

#include 

3.2 使用

先介绍一下 unordered_map 的前四个成员类型:

  • key_type 是第一个模板参数,即(Key)
  • mapped_type 是第二个模板参数,即(T)
  • value_type 是键值对 pair>
  • hasher 是第三个模板参数,即(Hash)
  • key_equal 是第四个模板参数,即(Pred)

        unordered_map 的使用与 map 非常类似(参考map即可),但是由于 unordered_map 使用哈希表实现,所以它的效率更高,适用于需要快速查找、插入和删除键值对的场景,注意 unordered_map 的迭代器是单向迭代器,只能++

还有一点,unordered_map 支持随机访问,即通过 Key 进行访问

这里解释跟 set 的 [] 一致,就不解释了

 测试代码

void Test()
{unordered_map count;string str[] = { "苹果", "西瓜", "香蕉", "草莓", "苹果", "西瓜", "苹果", "苹果", "西瓜", "苹果", "香蕉", "苹果", "香蕉" };for (auto& e : str){count[e]++;}for (auto& kv : count){cout << kv.first << ":" << kv.second << endl;}
}

运行结果

        unordered_map 对插入的元素进行去重的方式是根据键(key)是否已存在进行去重的。在 unordered_map 中,每个 key 只能对应一个值,因此如果插入了一个已存在的 key ,那不会进行插入。如果插入的 key 在 unordered_map 中不存在,那么该键值对将被插入到 unordered_map 中

例如:

#include 
#include 
#include 
using namespace std;int main() 
{unordered_map um;um.insert(make_pair(1, "apple"));um.insert(make_pair(2, "banana"));um.insert(make_pair(3, "cherry"));for (auto& it : um){cout << it.first << ": " << it.second << endl;}cout << endl;um.insert(make_pair(2, "orange")); // 插入已存在的键key,插入失败um.insert(make_pair(4, "orange"));// 插入不存在的键key,会插入新键值对  for (auto& e : um){cout << e.first << ": " << e.second << endl;}return 0;
}

运行结果

unordered系列的容器底层结构都是哈希表,下一篇介绍哈希表

----------------我是分割线---------------

文章到这里就结束了,下一篇即将更新

相关内容

热门资讯

linux入门---制作进度条 了解缓冲区 我们首先来看看下面的操作: 我们首先创建了一个文件并在这个文件里面添加了...
C++ 机房预约系统(六):学... 8、 学生模块 8.1 学生子菜单、登录和注销 实现步骤: 在Student.cpp的...
A.机器学习入门算法(三):基... 机器学习算法(三):K近邻(k-nearest neigh...
数字温湿度传感器DHT11模块... 模块实例https://blog.csdn.net/qq_38393591/article/deta...
有限元三角形单元的等效节点力 文章目录前言一、重新复习一下有限元三角形单元的理论1、三角形单元的形函数(Nÿ...
Redis 所有支持的数据结构... Redis 是一种开源的基于键值对存储的 NoSQL 数据库,支持多种数据结构。以下是...
win下pytorch安装—c... 安装目录一、cuda安装1.1、cuda版本选择1.2、下载安装二、cudnn安装三、pytorch...
MySQL基础-多表查询 文章目录MySQL基础-多表查询一、案例及引入1、基础概念2、笛卡尔积的理解二、多表查询的分类1、等...
keil调试专题篇 调试的前提是需要连接调试器比如STLINK。 然后点击菜单或者快捷图标均可进入调试模式。 如果前面...
MATLAB | 全网最详细网... 一篇超超超长,超超超全面网络图绘制教程,本篇基本能讲清楚所有绘制要点&#...
IHome主页 - 让你的浏览... 随着互联网的发展,人们越来越离不开浏览器了。每天上班、学习、娱乐,浏览器...
TCP 协议 一、TCP 协议概念 TCP即传输控制协议(Transmission Control ...
营业执照的经营范围有哪些 营业执照的经营范围有哪些 经营范围是指企业可以从事的生产经营与服务项目,是进行公司注册...
C++ 可变体(variant... 一、可变体(variant) 基础用法 Union的问题: 无法知道当前使用的类型是什...
血压计语音芯片,电子医疗设备声... 语音电子血压计是带有语音提示功能的电子血压计,测量前至测量结果全程语音播报࿰...
MySQL OCP888题解0... 文章目录1、原题1.1、英文原题1.2、答案2、题目解析2.1、题干解析2.2、选项解析3、知识点3...
【2023-Pytorch-检... (肆十二想说的一些话)Yolo这个系列我们已经更新了大概一年的时间,现在基本的流程也走走通了,包含数...
实战项目:保险行业用户分类 这里写目录标题1、项目介绍1.1 行业背景1.2 数据介绍2、代码实现导入数据探索数据处理列标签名异...
记录--我在前端干工地(thr... 这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 前段时间接触了Th...
43 openEuler搭建A... 文章目录43 openEuler搭建Apache服务器-配置文件说明和管理模块43.1 配置文件说明...