C++ 入门第 20 天:STL 容器之无序集合与无序多重集合
往期回顾:
C++ 入门17:STL 容器之映射(map)与多重映射(multimap)_-CSDN博客
C++ 入门18:STL 容器之栈(stack)与队列(queue)-CSDN博客
C++ 入门19:STL 容器之优先队列(priority_queue)-CSDN博客
C++ 入门第 20 天:STL 容器之无序集合与无序多重集合
一、前言
在之前的学习中,我们已经掌握了 set 和 multiset 容器,它们都是有序关联容器。但在某些场景下,我们并不关心元素的顺序,而是追求更高的性能。在这种情况下,C++ 提供了 无序容器,例如 unordered_set 和 unordered_multiset,它们的底层基于 哈希表(Hash Table) 实现,能够以常数时间完成插入、删除和查找操作。
1. 无序集合(unordered_set)
unordered_set 是一个 无序关联容器,用于存储不重复的元素。与 set 不同,unordered_set 的元素没有顺序,它的主要特点是:
- 底层实现:基于哈希表,操作效率高。
- 唯一性:不允许重复元素。
- 平均时间复杂度:插入、删除、查找的时间复杂度为 O(1)O(1)O(1)。
1.1 基本操作
以下是 unordered_set 的常用操作:
| 成员函数 | 功能说明 |
| insert(value) | 插入元素 |
| erase(value) | 删除指定元素 |
| find(value) | 查找元素,返回迭代器 |
| count(value) | 检查某元素是否存在(返回 0 或 1) |
| size() | 获取元素个数 |
| empty() | 检查容器是否为空 |
示例代码:基本操作
#include <iostream>
#include <unordered_set>
using namespace std;int main() {// 定义一个无序集合unordered_set<int> us;// 插入元素us.insert(10);us.insert(20);us.insert(30);us.insert(10); // 重复元素将被忽略// 遍历集合cout << "Elements in unordered_set: ";for (int elem : us) {cout << elem << " ";}cout << endl;// 查找元素if (us.find(20) != us.end()) {cout << "Element 20 is found in the unordered_set." << endl;}// 删除元素us.erase(10);cout << "After removing 10, elements in unordered_set: ";for (int elem : us) {cout << elem << " ";}cout << endl;return 0;
}
注意:输出的元素顺序与插入顺序无关,因为 unordered_set 使用哈希表存储数据。
1.2 哈希表的特性
无序集合通过哈希函数将值映射到特定的存储位置。哈希表的效率依赖于:
- 哈希函数:将值映射到存储位置。
- 装载因子(load factor):当前元素数量与桶数量的比值。过高时,哈希表会进行重新哈希(rehash)。
我们可以通过以下函数查看或修改哈希表的状态:
| 成员函数 | 功能说明 |
| bucket_count() | 返回桶的数量 |
| load_factor() | 返回装载因子 |
| max_load_factor(f) | 设置装载因子的上限 |
| rehash(n) | 强制重新哈希并至少设置 n 个桶 |
示例代码:查看哈希表状态
#include <iostream>
#include <unordered_set>
using namespace std;int main() {unordered_set<int> us = {10, 20, 30};cout << "Bucket count: " << us.bucket_count() << endl;cout << "Load factor: " << us.load_factor() << endl;// 强制重新哈希us.rehash(20);cout << "After rehash, bucket count: " << us.bucket_count() << endl;return 0;
}
2. 无序多重集合(unordered_multiset)
unordered_multiset 与 unordered_set 类似,不同点是:
- 允许重复元素:可以插入多个值相同的元素。
- 哈希表存储:仍然基于哈希表实现。
2.1 基本操作
unordered_multiset 的常用操作与 unordered_set 类似,但允许重复元素:
| 成员函数 | 功能说明 |
| insert(value) | 插入元素 |
| erase(value) | 删除指定元素 |
| count(value) | 返回某元素出现的次数 |
示例代码:无序多重集合
#include <iostream>
#include <unordered_set>
using namespace std;int main() {// 定义一个无序多重集合unordered_multiset<int> ums;// 插入元素ums.insert(10);ums.insert(20);ums.insert(10); // 允许重复// 遍历集合cout << "Elements in unordered_multiset: ";for (int elem : ums) {cout << elem << " ";}cout << endl; // 输出:10 20 10(顺序可能不同)// 查询某元素的出现次数cout << "Count of 10: " << ums.count(10) << endl;// 删除某个值的所有实例ums.erase(10);cout << "After removing 10, elements in unordered_multiset: ";for (int elem : ums) {cout << elem << " ";}cout << endl;return 0;
}
3. unordered_set 和 unordered_multiset 的性能分析
优点
- 高效:基于哈希表实现,插入、删除、查找的平均时间复杂度为 O(1)O(1)O(1)。
- 灵活:支持快速查找和重复值存储。
缺点
- 顺序无保证:无法保证元素存储顺序,适合只关心内容的场景。
- 哈希冲突:当冲突较多时,性能可能下降,接近 O(n)O(n)O(n)。
对比:set vs unordered_set
| 特性 | set | unordered_set |
| 底层结构 | 红黑树 | 哈希表 |
| 是否有序 | 有序 | 无序 |
| 查找时间复杂度 | O(logn)O(\log n)O(logn) | O(1)O(1)O(1)(平均情况) |
| 插入、删除时间复杂度 | O(logn)O(\log n)O(logn) | O(1)O(1)O(1)(平均情况) |
4. 实际应用场景
- 去重:
unordered_set适合需要去重但不关心顺序的场景,例如统计某一组数据中不重复的值。 - 频率统计:
unordered_multiset可以用来统计某些值的出现次数。 - 高效查找:在大规模数据中快速查找是否存在某元素。
示例:统计字符串中单词出现次数
使用
unordered_multiset来统计一个字符串中单词的频率。示例代码
#include <iostream> #include <unordered_set> #include <sstream> #include <string> using namespace std;int main() {string text = "hello world hello C++ world";unordered_multiset<string> wordCount;// 将字符串分割为单词stringstream ss(text);string word;while (ss >> word) {wordCount.insert(word);}// 输出每个单词的出现次数for (const string& w : wordCount) {cout << w << ": " << wordCount.count(w) << endl;wordCount.erase(w); // 删除已处理的单词}return 0; }结语
以上就是 C++ 标准模板库中的无序集合与无序多重集合的基础知识点了。这些无序容器通过哈希表实现,能够提供极高的操作效率,适用于需要快速查找、插入和删除的场景。掌握无序集合与无序多重集合的使用,基本上在开发中都会用到的,大家多看看,一定要掌握。
-
都看到这里了,点个赞再走呗朋友~
-
加油吧,预祝大家变得更强!
相关文章:
C++ 入门第 20 天:STL 容器之无序集合与无序多重集合
往期回顾: C 入门17:STL 容器之映射(map)与多重映射(multimap)_-CSDN博客 C 入门18:STL 容器之栈(stack)与队列(queue)-CSDN博客 C 入门19&#x…...
devops-部署Harbor实现私有Docker镜像仓库
文章目录 概述下载配置安装安装后生成的文件使用和维护Harbor参考资料 概述 Harbor是一个开源注册中心,它使用策略和基于角色的访问控制来保护工件,确保镜像被扫描并且没有漏洞,并将镜像签名为可信的。Harbor是CNCF的一个毕业项目࿰…...
rebase ‘A‘ onto ‘master‘ 和 merge ‘master‘ into ‘A‘有什么区别
在Git版本控制系统中,rebase 和 merge 是两种不同的操作,用于合并分支。rebase A onto master 和 merge master into A 虽然最终目的都是将两个分支的更改合并在一起,但它们在处理方式和结果上有所不同。 rebase ‘A’ onto ‘master’ 含义…...
Vulhub:Jackson[漏洞复现]
CVE-2017-7525(Jackson反序列化) 启动漏洞环境 docker-compose up -d 阅读vulhub给出的漏洞文档 cat README.zh-cn.md # Jackson-databind 反序列化漏洞(CVE-2017-7525) Jackson-databind 支持 [Polymorphic Deserialization](https://github.com/Fas…...
strongswan构建测试环境
make-testing脚本文件负责构建strongswan的虚拟化测试系统。位于目录strongswan-5.9.14/testing/,需要以管理员身份运行make-testing。生成测试用到的虚拟客户机镜像,KVM虚拟机和虚拟网络的配置文件位于目录:config/kvm。 ~/strongswan-5.9.14/testing$…...
前端:金额高精度处理
Decimal 是什么 想必大家在用js 处理 数字的 加减乘除的时候,或许都有遇到过 精度不够 的问题,还有那些经典的面试题 0.20.1 ! 0.3, 至于原因,那就是 js 计算底层用的是 IEEE 754 ,精度上有限制, 那么Deci…...
面试题整理3----nc命令的常见用法
面试题整理3----nc命令的常见用法 1. NC是什么2. NC的常用参数2.1 开启指定端口TCP监听(-l小写的L)2.2 测试端口是否能访问(-v)2.3 开启指定端口UDP监听(-u)2.4 端口扫描(-z)2.5 指定超时时间(-w)2.6 指定本地端口号连接(-p)2.7 指定的命令(-e) 1. NC是什么 nc(Net…...
Trimble天宝三维激光扫描仪在建筑工程竣工测量中的应用【沪敖3D】
竣工测量是建筑项目竣工阶段的一个至关重要的环节,它为建筑工程的质量验收和成果核查提供了核心的参考依据。传统的竣工测量方法,如全站仪测量,主要依赖于现场人工操作,存在一些明显的局限性,例如作业时间长、工作量大…...
IntelliJ IDEA 使用技巧与插件推荐
目录 常用使用技巧 1. 使用快捷键提升开发效率 2. 多光标编辑 3. 代码自动补全 4. 使用 Find Action 快速执行操作 5. 集成版本控制系统(VCS) 6. 快速查看代码文档 推荐插件 1. Lombok Plugin 2. Rainbow Brackets 3. Key Promoter X 4. Chec…...
Oracle 技术精选学习
Oracle 技术犹如一座闪耀着无尽光芒的灯塔,为众多 IT 从业者和技术爱好者照亮了前行的道路。无论是数据库管理、企业应用开发还是数据分析,Oracle 都以其强大、稳定和广泛的应用而占据着行业的重要地位。学习 Oracle 技术,更是能为个人带来诸…...
sqlilabs第三十关到第三十五关靶场攻略
第三十关 第三十关和二十九关差不多,将单引号换成双引号 查询表名,字段名,数据 ?id1&id-2" union select 1,group_concat(table_name),3 from information_schema.tables where table_schemadatabase()-- ?id1&id-2" …...
windows免登录linux
windows 生成秘钥文件 ssh-keygen -t rsa 将公钥传送到服务器 scp C:\Users\xx/.ssh/id_rsa.pub xxxx:/home/ruoyi/id_rsa.pub linux 使用ssh-copy-id -i ~/.ssh/id_rsa.pub userhost 如果禁用root登录,先开启 vim /etc/ssh/sshd_config PermitRootLogin yes …...
matlab绘图时设置左、右坐标轴为不同颜色
目录 一、需求描述 二、实现方法 一、需求描述 当图中存在两条曲线,需要对两条曲线进行分别描述时,应设置左、右坐标轴为不同颜色,并设置刻度线,且坐标轴颜色需要和曲线颜色相同。 二、实现方法 1.1、可以实现: 1…...
springboot+javafx使用aop切面导致的fx:id不能被注入问题
记录一个我遇到得问题 问题描述 我本来使用AOP切面来进行全局异常管理,但是使用AOP之后fxml中通过fx:id绑定得参数无法被注入 Slf4j Component Aspect public class GlobalExceptionAspect {AfterThrowing(pointcut "execution(* com.shkj.videoclassifica…...
说说你对java lambda表达式的理解?
大家好,我是锋哥。今天分享关于【说说你对java lambda表达式的理解?】面试题。希望对大家有帮助; 说说你对java lambda表达式的理解? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 Java Lambda 表达式是 Java 8 引入的一项重要特性&#…...
优化你的 3D Tiles:性能与质量的平衡
优化你的 3D Tiles:性能与质量的平衡 在现代的三维场景渲染中,3D Tiles 是一种强大的技术,它能以高效、分级加载的方式呈现海量的三维数据。然而,优化 3D Tiles 以实现性能与质量的平衡,却是一个复杂且关键的任务。本…...
【数据结构——线性表】单链表的基本运算(头歌实践教学平台习题)【合集】
目录😋 任务描述 相关知识 测试说明 我的通关代码: 测试结果: 任务描述 本关任务:编写一个程序实现单链表的基本运算。 相关知识 为了完成本关任务,你需要掌握:初始化线性表、销毁线性表、判定是否为空表、求线性…...
设计模式之桥接模式:抽象与实现之间的分离艺术
~犬📰余~ “我欲贱而贵,愚而智,贫而富,可乎? 曰:其唯学乎” 桥接模式概述与角色组成 想象一下你家里的电视遥控器,无论是索尼还是三星的电视机,遥控器的按键功能都差不多࿱…...
网络隧道与代理
文章目录 网络隧道网络代理参考 网络隧道 使用隧道的原因是在不兼容的网络上传输数据,或在不安全网络上提供一个安全路径。网络隧道的一个典型特征就是封装报文和对报文加密。如下是两个典型的案例:IPv4到IPv6的迁移、VPN。 图3.1 IPv4到IPv6的迁移 图…...
游戏关卡分析:荒野大镖客2雪山终战
1、相关剧情 主角约翰一家在农场过着悠闲的日子,突然平静被打破, 女枪手来报信,在某小镇找到了迈卡的消息。 于是激发了约翰的满腔怒气,不顾妻子的反对,坚决要出战, 要彻底歼灭迈卡,为亚瑟…...
谷歌浏览器插件
项目中有时候会用到插件 sync-cookie-extension1.0.0:开发环境同步测试 cookie 至 localhost,便于本地请求服务携带 cookie 参考地址:https://juejin.cn/post/7139354571712757767 里面有源码下载下来,加在到扩展即可使用FeHelp…...
云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?
大家好,欢迎来到《云原生核心技术》系列的第七篇! 在上一篇,我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在,我们就像一个拥有了一块崭新数字土地的农场主,是时…...
Ubuntu系统下交叉编译openssl
一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机:Ubuntu 20.04.6 LTSHost:ARM32位交叉编译器:arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...
FastAPI 教程:从入门到实践
FastAPI 是一个现代、快速(高性能)的 Web 框架,用于构建 API,支持 Python 3.6。它基于标准 Python 类型提示,易于学习且功能强大。以下是一个完整的 FastAPI 入门教程,涵盖从环境搭建到创建并运行一个简单的…...
剑指offer20_链表中环的入口节点
链表中环的入口节点 给定一个链表,若其中包含环,则输出环的入口节点。 若其中不包含环,则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...
Python爬虫(二):爬虫完整流程
爬虫完整流程详解(7大核心步骤实战技巧) 一、爬虫完整工作流程 以下是爬虫开发的完整流程,我将结合具体技术点和实战经验展开说明: 1. 目标分析与前期准备 网站技术分析: 使用浏览器开发者工具(F12&…...
Caliper 配置文件解析:config.yaml
Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...
【论文阅读28】-CNN-BiLSTM-Attention-(2024)
本文把滑坡位移序列拆开、筛优质因子,再用 CNN-BiLSTM-Attention 来动态预测每个子序列,最后重构出总位移,预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵(S…...
Linux --进程控制
本文从以下五个方面来初步认识进程控制: 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程,创建出来的进程就是子进程,原来的进程为父进程。…...
中医有效性探讨
文章目录 西医是如何发展到以生物化学为药理基础的现代医学?传统医学奠基期(远古 - 17 世纪)近代医学转型期(17 世纪 - 19 世纪末)现代医学成熟期(20世纪至今) 中医的源远流长和一脉相承远古至…...
