C++第三十九弹---C++ STL中的无序容器:unordered_set与unordered_map使用详解
✨个人主页: 熬夜学编程的小林
💗系列专栏: 【C语言详解】 【数据结构详解】【C++详解】
目录
1 unordered_set
1.1 unordered_set的接口说明
1.1.1 unordered_set的构造
1.1.2. unordered_set的容量
1.1.3. unordered_set的迭代器
1.1.4. unordered_set的查询
1.1.5. unordered_set的修改操作
1.1.6. unordered_set的桶操作
2 unordered_map
1.2 unordered_map的接口说明
1.2.1. unordered_map的构造
1.2.2. unordered_map的容量
1.2.3. unordered_map的迭代器
1.2.4. unordered_map的元素访问
6. unordered_map的修改操作
7. unordered_map的桶操作
在C++98中,STL提供了底层为红黑树结构的一系列关联式容器,在查询时效率可达到log2 N,即最差情况下需要比较红黑树的高度次,当树中的节点非常多时,查询效率也不理想。最好的查询是,进行很少的比较次数就能够将元素找到,因此在C++11中,STL又提供了4个unordered系列的关联式容器,这四个容器与红黑树结构的关联式容器使用方式基本类似,只是其底层结构不同,本文中只对unordered_map和unordered_set进行介绍。
1 unordered_set
- 1. unordered_set 是以不特定顺序存储唯一元素的容器,并允许根据其值快速检索单个元素。
- 2. 在unordered_set中,元素的值同时是其键,它唯一地标识它。键是不可变的,因此,unordered_set中的元素不能在容器中修改一次,但是,它们可以插入和删除。
- 3. 在内部,unordered_set中的元素不按任何特定顺序排序,而是根据其哈希值组织到桶中,以便直接通过其值快速访问各个元素(平均平均时间复杂度恒定)。
- 4. unordered_set容器通过其键访问单个元素的速度比设置的容器更快,尽管它们在通过其元素子集进行范围迭代时通常效率较低。
- 5. 容器中的迭代器至少是正向迭代器。
1.1 unordered_set的接口说明
1.1.1 unordered_set的构造
代码演示
#include<unordered_set>
int main()
{// 构造空对象unordered_set<int> s1;// 列表构造对象unordered_set<int> s2 = { 1,3,4,9,2,7 };return 0;
}
测试结果
1.1.2. unordered_set的容量
函数声明 | 功能介绍 |
---|---|
bool empty() const | 检测unordered_set是否为空 |
size_t size() const | 获取unordered_set的有效元素个数 |
代码演示
#include<unordered_set>
int main()
{unordered_set<int> s1 = { 1,3,4,9,2,7 };cout << "empty() = " << s1.empty() << endl;cout << "size() = " << s1.size() << endl;return 0;
}
测试结果
1.1.3. unordered_set的迭代器
函数声明 | 功能介绍 |
---|---|
begin | 返回unordered_set第一个元素的迭代器 |
end | 返回unordered_set最后一个元素下一个位置的迭代器 |
代码演示
#include<unordered_set>
int main()
{unordered_set<int> s1 = { 1,3,4,9,2,7 };// 获取unordered_set第一个元素的迭代器unordered_set<int>::iterator it1 = s1.begin();while (it1 != s1.end()){cout << *it1 << " ";++it1;}cout << endl;return 0;
}
测试结果
1.1.4. unordered_set的查询
函数声明 | 功能介绍 |
---|---|
iterator find(const K& key) | 返回key在哈希桶中的位置 |
size_t count(const K& key) | 返回哈希桶中key的个数 |
代码演示
#include<unordered_set>
int main()
{unordered_set<int> s1 = { 1,3,4,9,2,7,4 };// 查找数值3的位置,并打印该位置的值auto pos = s1.find(3);cout << *pos << endl;// 计算数值4的个数size_t countFour = s1.count(4);cout << "countFour = " << countFour << endl;return 0;
}
测试结果
注意:unordered_set中key是不能重复的,因此count函数的返回值最大为1。
1.1.5. unordered_set的修改操作
函数声明 | 功能介绍 |
---|---|
insert | 向容器中插入key值 |
erase | 删除容器中的key值 |
void clear() | 清空容器中有效元素个数 |
void swap(unordered_set&) | 交换两个容器中的元素 |
代码演示
#include<unordered_set>
int main()
{unordered_set<int> s1;// 插入值s1.insert(1);s1.insert(4);s1.insert(5);// 支持迭代器,因此也支持范围forfor (auto e : s1){cout << e << " ";}cout << endl;// 删除6,没有该值则不删除s1.erase(6);// 删除4,有该值则删除该值s1.erase(4);for (auto e : s1){cout << e << " ";}cout << endl;return 0;
}
测试结果
1.1.6. unordered_set的桶操作
函数声明 | 功能介绍 |
---|---|
size_t bucket_count()const | 返回哈希桶中桶的总个数 |
size_t bucket_size(size_t n)const | 返回n号桶中有效元素的总个数 |
size_t bucket(const K& key) | 返回元素key所在的桶号 |
代码演示
#include<unordered_set>
int main()
{unordered_set<int> s1 = { 1,4,6,9,3,7,5 };// 获取桶的总个数cout << "bucket_count() = " << s1.bucket_count() << endl;// 获取2号桶有效元素个数cout << "bucket_size(2) = " << s1.bucket_size(2) << endl;// 数值6所在的桶号cout << "bucket(6) = " << s1.bucket(6) << endl;return 0;
}
测试结果
2 unordered_map
- 1. unordered_map是存储<key, value>键值对的关联式容器,其允许通过key快速的索引到与其对应的value。
- 2. 在unordered_map中,键值通常用于惟一地标识元素,而映射值是一个对象,其内容与此键关联。键和映射值的类型可能不同。
- 3. 在内部,unordered_map没有对<kye, value>按照任何特定的顺序排序, 为了能在常数范围内找到key所对应的value,unordered_map将相同哈希值的键值对放在相同的桶中。
- 4. unordered_map容器通过key访问单个元素要比map快,但它通常在遍历元素子集的范围迭代方面效率较低。
- 5. unordered_maps实现了直接访问操作符(operator[]),它允许使用key作为参数直接访问value。
- 6. 它的迭代器至少是前向迭代器。
1.2 unordered_map的接口说明
1.2.1. unordered_map的构造
函数声明 | 功能介绍 |
---|---|
unordered_map | 构造一个空的 unordered_map 对象 |
unordered_map(initializer_list<T> il) | 使用列表的内容初始化容器。 |
代码演示
#include<unordered_map>
int main()
{// 构造空对象unordered_map<string,int> m1;// 列表构造对象unordered_map<string, string> m2 = {{"insert","插入"},{"erase","删除"},{"string","字符串"} };return 0;
}
测试结果
1.2.2. unordered_map的容量
函数声明 | 功能介绍 |
---|---|
bool empty() const | 检测unordered_map是否为空 |
size_t size() const | 获取unordered_map的有效元素个数 |
代码演示
#include<unordered_map>
int main()
{unordered_map<string, string> m1 = {{"insert","插入"},{"erase","删除"},{"string","字符串"} };cout << "empty() = " << m1.empty() << endl;cout << "size() = " << m1.size() << endl;return 0;
}
测试结果
1.2.3. unordered_map的迭代器
函数声明 | 功能介绍 |
---|---|
begin | 返回unordered_map第一个元素的迭代器 |
end | 返回unordered_map最后一个元素下一个位置的迭代器 |
代码演示
#include<unordered_map>
int main()
{unordered_map<string, string> m1 = {{"insert","插入"},{"erase","删除"},{"string","字符串"} };// 获取第一个元素的迭代器,使用auto更简便//unordered_map<string, string>::iterator it = m1.begin();auto it = m1.begin();while (it != m1.end()){cout << it->first << ":" << it->second << endl;++it;}cout << endl;return 0;
}
测试结果
1.2.4. unordered_map的元素访问
函数声明 | 功能介绍 |
---|---|
operator[] | 返回与key对应的value,没有一个默认值 |
代码演示
#include<unordered_map>
int main()
{// 统计各自水果的个数string arr[] = { "苹果", "西瓜", "苹果", "西瓜", "苹果", "苹果", "西瓜","苹果", "香蕉", "苹果", "香蕉","苹果","草莓", "苹果","草莓" };unordered_map<string, int> countMap;for (auto& e : arr){// 水果没有出现则插入该水果,出现则将个数++countMap[e]++;}for (auto& kv : countMap){cout << kv.first << ":" << kv.second << endl;}cout << endl;return 0;
}
测试结果
注意:该函数中实际调用哈希桶的插入操作,用参数key与V()构造一个默认值往底层哈希桶中插入,如果key不在哈希桶中,插入成功,返回V(),插入失败,说明key已经在哈希桶中,将key对应的value返回。此处与map中的operator[]原理类似。
1.2.5. unordered_map的查询
函数声明 | 功能介绍 |
---|---|
iterator find(const K& key) | 返回key在哈希桶中的位置 |
size_t count(const K& key) | 返回哈希桶中关键码为key的键值对的个数 |
代码演示
#include<unordered_map>
int main()
{unordered_map<string, int> m1 = {{"string",1 }, { "insert",2 }, { "left",3 } };// 查找left的位置,打印该位置键值对的值auto pos = m1.find("left");cout << pos->first << ":" << pos->second << endl;// 计算key为string的键值对个数size_t count = m1.count("string");cout << "count = " << count << endl;return 0;
}
测试结果
注意:unordered_map中key是不能重复的,因此count函数的返回值最大为1。
6. unordered_map的修改操作
函数声明 | 功能介绍 |
---|---|
insert | 向容器中插入键值对 |
erase | 删除容器中的键值对 |
void clear() | 清空容器中有效元素个数 |
void swap(unordered_map&) | 交换两个容器中的元素 |
代码演示
#include<unordered_map>
int main()
{unordered_map<string, int> m1;pair<string, int> kv1("string", 1);// 插入值m1.insert(kv1);// 有名对象m1.insert({ "left",2 });m1.insert(make_pair("right", 3));for (auto e : m1){cout << e.first << ":" << e.second << endl;}cout << endl;// 删除key为string的键值对m1.erase("string");for (auto e : m1){cout << e.first << ":" << e.second << endl;}cout << endl;return 0;
}
测试结果
7. unordered_map的桶操作
函数声明 | 功能介绍 |
---|---|
size_t bucket_count()const | 返回哈希桶中桶的总个数 |
size_t bucket_size(size_t n)const | 返回n号桶中有效元素的总个数 |
size_t bucket(const K& key) | 返回元素key所在的桶号 |
代码演示
#include<unordered_map>
int main()
{unordered_map<string, int> m1 = {{"string",1},{"right",2},{"insert",3}};// 获取桶的总个数cout << "bucket_count() = " << m1.bucket_count() << endl;// 获取3号桶有效元素个数cout << "bucket_size(2) = " << m1.bucket_size(3) << endl;// key为right所在的桶号cout << "bucket(right) = " << m1.bucket("right") << endl;return 0;
}
测试结果
相关文章:

C++第三十九弹---C++ STL中的无序容器:unordered_set与unordered_map使用详解
✨个人主页: 熬夜学编程的小林 💗系列专栏: 【C语言详解】 【数据结构详解】【C详解】 目录 1 unordered_set 1.1 unordered_set的接口说明 1.1.1 unordered_set的构造 1.1.2. unordered_set的容量 1.1.3. unordered_set的迭代器 1.1…...

数学建模起步感受(赛前15天)
0基础直接上手数模,因为大一!年轻就是无所畏惧!开个玩笑,因为数模比赛比一年少一年… 抱着不打也是浪费的态度,我开始着手准备 首先python啥也不会,知道有元组这玩意… 仅仅在刷软考题的时候遇到python选择…...

【YOLO5 项目实战】(4)红外目标检测
欢迎关注『youcans动手学模型』系列 本专栏内容和资源同步到 GitHub/youcans 【YOLO5 项目实战】(1)YOLO5 环境配置与测试 【YOLO5 项目实战】(2)使用自己的数据集训练目标检测模型 【YOLO5 项目实战】(3)P…...

游泳耳机哪个牌子好?角逐必选榜的4大王者游泳耳机测评解析!
在选择游泳耳机时,许多消费者往往会被市场上五花八门的产品所困扰。特别是那些标榜能够防水防潮的产品,但实际上它们往往缺乏核心技术支持,存在很高的损伤风险。据调查,超过90%的用户反映,市面上的游泳耳机常常无法达到…...

鹤岗房全国蔓延,现在要不要买房?
文|琥珀食酒社 作者 | 积溪 房子卖白菜价、人人都能买得起的时代 真的要来了 以前啊你花2万块钱 在大城市买不到一个厕所 可现在只要几万块你就能买一整套房 还带装修和家电 而且这样的房子还很多 “鹤岗”房已经在全国快速蔓延 那对咱普通人来说到底是好…...

Flink程序部署与提交
前言 我们看门见山,生产环境一般用的是在YARN上面采用应用模式进行部署flink程序。实际生产中一般需要和资源管理平台(如YARN)结合起来,选择特定的模式来分配资源、部署应用。 部署模式 在一些应用场景中,对于集群资源分配和占用的方式,可能会有特定的需求。Flink 为各…...

了解Android
Android 系统架构 从图中可以看出,整个Android操作系统分为五层。它们分别是: 内核层 Android系统是基于Linux内核的,这一层为Android设备的各种硬件提供了底层的驱动。硬件抽象层 该层为硬件厂商定义了一套标准的接口。这样可以在不影响上层…...

Tomcat学习进阶
目录 Apache Tomcat架构配置线程模型Tomcat 的类加载机制类加载器层次结构类加载流程 Tomcat 的优化策略Tomcat 的集群部署Tomcat故障排查 Apache Tomcat 架构配置 Apache Tomcat是一个开源的Java Servlet容器和Web服务器,它实现了Java EE规范中的Servlet和JSP API。…...

【C++】————智能指针
作者主页: 作者主页 本篇博客专栏:C 创作时间 :2024年8月20日 一,什么是智能指针 在C中没有垃圾回收机制,必须自己释放分配的内存,否则就会造成内存泄露。解决这个问题最有效的方法是使用智能指针&…...
GT IP中CC序列(Clock Correction Sequence)的周期性
CC序列(Clock Correction Sequence),即时钟校正序列,在数字通信中扮演着至关重要的角色。这一序列的周期性插入机制,旨在确保发送器和接收器之间的时钟同步,从而维持数据传输的准确性和稳定性。以下是CC序列…...
grafana pod 无法启动 Only one datasource per organization can be marked as default
标题信息 helm 部署的 prometheus 全栈监控 chart 为 prometheus-community/kube-prometheus-stack helm 部署的 loki 日志系统 chart 为 grafana/loki-stack 问题描述 grafana pod 启动不了,查看该pod 日志报错如下 logger=provisioning t=2024-08-21T06:42:45.954318228…...

你是如何克服编程学习中的挫折感的?(-@-^-0-)
在编程学习中遇到挫折感是极为常见且正常的现象,因为编程往往涉及解决复杂问题、理解抽象概念以及不断试错的过程。 以下是一些建议,帮助你在面对挫折时调整心态,继续前行: 接受失败是成长的一部分:首先要认识到&#…...
大数据技术之Zookeeper(1)
目录 Zookeeper 入门 概述 Zookeeper的主要特点包括: Zookeeper的应用场景: Zookeeper的基本概念: 架构: Zookeeper工作机制 Zookeeper数据结构 Znode(Zookeeper Node) Znode的类型 Znode路径 Znode属性 Wa…...
鸿蒙学习(四):泛型空安全模块导入导出
泛型与函数 泛型类型和函数允许创建的代码在各种类型上运行,而不仅支持单一类型。 泛型类和接口(Element) 类和接口可以定义为泛型,将参数添加到类型定义中,如以下示例中的类型参数Element: class CustomStack<Element>…...
无人机(Unmanned Aerial Vehicle, UAV)视觉感知论文汇总
综述类 A Survey of Object Detection for UAVs Based on Deep LearningDeep Learning for UAV-based Object Detection and Tracking:A surveyMoving Target Tracking by Unmanned Aerial Vehicle:A Survey and TaxonomyVision-Based Learning for Dro…...
【ORACLE】 ORA-01691: Lob 段无法通过 8192 (在表空间 XXX_SPACE 中) 扩展
ORA-01691错误通常表示Oracle数据库在尝试扩展LOB段时无法为表空间分配更多的空间。这个问题通常由表空间容量不足引起。根据搜索结果,以下是几种可能的解决方案: 检查并扩大表空间:首先,确认表空间是否已经达到其最大容量。可以使…...
Java之静态代理与动态代理的区别
🍁 作者:知识浅谈,CSDN签约讲师,CSDN博客专家,华为云云享专家,阿里云专家博主 📌 擅长领域:全栈工程师、爬虫、ACM算法 🔥 微信:zsqtcyw 联系我领取学习资料 …...

公司内网监控软件有哪些?(2024年10款最新款推荐内网监控软件)
在2024年,公司内网监控软件市场提供了多种选择,以满足不同企业的监控需求。 以下是一些值得推荐的最新款内网监控软件: 1. Performance Monitor 核心功能:不仅是一款局域网监控软件,更是一个全面的内网安全管理解决方…...
CUDA编程07 - 卷积的优化
一:概述 在接下来的几篇文章中,我们将讨论一组重要的并行计算模式。这些模式是许多并行算法的基础,这些算法出现在许多并行应用中。我们将从卷积开始,卷积是一种流行的数组操作,广泛应用于信号处理、数字录音、图像处理、视频处理和计算机视觉等领域。在这些应用领域中,卷…...

解锁高效办公新姿势:SSO单点登录+企业网盘完美搭配
在现代互联网环境中,随着企业业务的不断扩展,多系统、多应用的集成成为常态。为了提升用户体验,减少用户在不同系统间切换的繁琐,单点登录(SSO, Single Sign-On)技术应运而生。 本文将详细介绍SSO单点登录的…...

关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案
问题描述:iview使用table 中type: "index",分页之后 ,索引还是从1开始,试过绑定后台返回数据的id, 这种方法可行,就是后台返回数据的每个页面id都不完全是按照从1开始的升序,因此百度了下,找到了…...

【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例
文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...

页面渲染流程与性能优化
页面渲染流程与性能优化详解(完整版) 一、现代浏览器渲染流程(详细说明) 1. 构建DOM树 浏览器接收到HTML文档后,会逐步解析并构建DOM(Document Object Model)树。具体过程如下: (…...

2021-03-15 iview一些问题
1.iview 在使用tree组件时,发现没有set类的方法,只有get,那么要改变tree值,只能遍历treeData,递归修改treeData的checked,发现无法更改,原因在于check模式下,子元素的勾选状态跟父节…...
【git】把本地更改提交远程新分支feature_g
创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问(基础概念问题) 1. 请解释Spring框架的核心容器是什么?它在Spring中起到什么作用? Spring框架的核心容器是IoC容器&#…...

2025年渗透测试面试题总结-腾讯[实习]科恩实验室-安全工程师(题目+回答)
安全领域各种资源,学习文档,以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具,欢迎关注。 目录 腾讯[实习]科恩实验室-安全工程师 一、网络与协议 1. TCP三次握手 2. SYN扫描原理 3. HTTPS证书机制 二…...

基于Springboot+Vue的办公管理系统
角色: 管理员、员工 技术: 后端: SpringBoot, Vue2, MySQL, Mybatis-Plus 前端: Vue2, Element-UI, Axios, Echarts, Vue-Router 核心功能: 该办公管理系统是一个综合性的企业内部管理平台,旨在提升企业运营效率和员工管理水…...
Vue3中的computer和watch
computed的写法 在页面中 <div>{{ calcNumber }}</div>script中 写法1 常用 import { computed, ref } from vue; let price ref(100);const priceAdd () > { //函数方法 price 1price.value ; }//计算属性 let calcNumber computed(() > {return ${p…...
【实施指南】Android客户端HTTPS双向认证实施指南
🔐 一、所需准备材料 证书文件(6类核心文件) 类型 格式 作用 Android端要求 CA根证书 .crt/.pem 验证服务器/客户端证书合法性 需预置到Android信任库 服务器证书 .crt 服务器身份证明 客户端需持有以验证服务器 客户端证书 .crt 客户端身份…...