C++第三十九弹---C++ STL中的无序容器:unordered_set与unordered_map使用详解

news2024/11/15 15:54:17

个人主页: 熬夜学编程的小林

💗系列专栏: 【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);
	// 支持迭代器,因此也支持范围for
	for (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;
}

测试结果 

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

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

相关文章

电子电路学习之电感

电感作用&#xff1a;电感具有“通直流&#xff0c;阻交流”的作用&#xff0c;即对交流电具有阻碍作用&#xff0c;频率越高&#xff0c;阻抗越大。 电感类型&#xff1a;贴片和直插 电感参数&#xff1a; (1) 精度&#xff1a;电感精度一般为30&#xff05; (2)直流电阻(DC…

JS获取当前设备名称

在JavaScript中&#xff0c;没有直接获取“当前设备名称”的标准方法&#xff0c;因为这通常涉及访问底层系统信息&#xff0c;而JavaScript在浏览器中运行时通常无权访问这些信息。不过&#xff0c;可以通过用户代理字符串&#xff08;User-Agent string&#xff09;来间接推断…

Facebook的区块链战略:如何在社交媒体中实现去中心化

随着区块链技术的发展&#xff0c;Facebook&#xff08;现Meta&#xff09;正积极探索如何将这一技术整合进其社交平台中&#xff0c;以提升用户体验和数据安全。区块链技术以去中心化、透明性和不可篡改性为特点&#xff0c;为社交媒体带来了新的可能性。本文将探讨Facebook在…

若依平台/vue2引入代码编辑器(monaco-editor)

需求背景&#xff1a;需要在线编辑javascript代码&#xff0c;方便维护&#xff0c;有些更新不需要再重新部署 一、安装依赖 "monaco-editor": "^0.30.1", "monaco-editor-webpack-plugin": "^6.0.0", 二、 vue.config.js中添加如下配…

How to check the validity of the OpenAI key from python?

题意&#xff1a;如何在 Python 中检查 OpenAI 密钥的有效性&#xff1f; 问题背景&#xff1a; https://pypi.org/project/openai/ "The library needs to be configured with your accounts secret key which is available on the website. [...] Set it as the OPENAI…

RxJava-操作符-mergeDelayError使用

说明 合并多个源Observable的事件&#xff0c;事件不是按照顺序被发射&#xff08;如需顺序使用concat操作符&#xff09;。Error事件被延迟发射&#xff0c;针对的是源Observable中的Error事件&#xff0c;多个源Observable都有Error时&#xff0c;会合并Error事件。执行结束 …

vba自动发送邮件的基础步骤?有哪些流程?

vba自动发送邮件如何设置&#xff1f;vba自动发送邮件的技巧&#xff1f; 如果你想节省时间&#xff0c;提高工作效率&#xff0c;学会如何使用VBA自动发送邮件是一个非常有用的技能。AokSend将为你介绍VBA自动发送邮件的基础步骤&#xff0c;并通过简单的分段来详细讲解。 v…

《黑神话:悟空》的发布是否能打开元宇宙游戏世界的门

四年漫长等待&#xff0c;8月20日&#xff0c;国产3A游戏巨制《黑神话&#xff1a;悟空》正式上线并彻底引爆全球市场。这背后不仅是中国游戏史的里程碑&#xff0c;也将为元宇宙的未来夯实地基&#xff01; 游戏上线后&#xff0c;热度持续飙升&#xff0c;成为了社交媒体和游…

【数据结构与算法】并行搜索

并行搜索目录 一.并行的基础知识1.进程2.线程 二.正常遍历搜索三.线程并发搜索1.线程身份证和句柄2.创建线程3.搜索结构体4.处理函数实现 四.完整代码 一.并行的基础知识 1.进程 说的简单点,进程就是计算机中的多个程序,就相当于多个软件. 比如我同时打开QQ和WX,那么这个就叫…

基于yolov5 人体行为检测 对 跌倒 站立 蹲下 坐下 跑 五种行为检测目标检测

该项目使用YOLOv5深度学习框架来检测图像或视频中人体的五种基本行为&#xff1a;跌倒、站立、蹲下、坐下和跑步。YOLOv5&#xff08;You Only Look Once v5&#xff09;是一种高效的物体检测模型&#xff0c;能够快速准确地识别出图像中的目标。本项目具有以下特点&#xff1a…

秋招力扣Hot100刷题总结——动态规划

一、01背包 01背包问题中&#xff0c;遍历顺序可以是先物品后背包&#xff0c;也可以是先背包后物品&#xff0c;但是背包要倒序遍历。 1. 等和子集 题目要求&#xff1a;给你一个 只包含正整数 的 非空 数组 nums 。请你判断是否可以将这个数组分割成两个子集&#xff0c;使…

【芯智雲城】星宸科技Sigmastar SSD101芯片_高清显示解决方案

一、方案描述&#xff1a; Sigmastar SSD101是高度集成高性能的display controller,支持模拟的NTSC/PAL/SECAM CVBS和S-video信号输入,可自动检测视频信号源和模式&#xff0c;可自如地切换不同的信号源,内置2D梳状滤波器和AGC,支持6-bit/8-bit TTL/TCON显示屏。芯片LQFP 64pi…

基于大型语言模型的应急人机协同救援关键技术

源自&#xff1a;指挥与控制学报 作者&#xff1a;石响 王天乐 夏乾臣 陈善广 注&#xff1a;若出现显示不完全的情况&#xff0c;可 V 搜索“人工智能技术与咨询”查看完整文章 人工智能、大数据、多模态大模型、计算机视觉、自然语言处理、数字孪生、深度强化学习 课程…

大屏畅玩游戏,小米SU7迎来大升级,可连接蓝牙游戏手柄

嘿&#xff0c;朋友们&#xff01;今天我要和你们分享一个令人兴奋的消息。 小米SU7汽车迎来了一次重大升级&#xff0c;这不仅仅是技术上的飞跃&#xff0c;更是为驾驶体验带来了革命性的变化。想象一下&#xff0c;在宽敞的车内&#xff0c;通过连接蓝牙游戏手柄&#xff0c…

R语言绘图系列专栏 | 更新中

关于**《R语言绘图专栏》**&#xff0c;此专栏基于R语言绘制图形。每个图形我们会提供对应的R代码、数据和文本文档。此系列将会是一个长期更新的系列。 本系列教程&#xff0c;我们计划发表及收录使用R语言绘制50科研中常用图形。这是个长期的过程&#xff0c;计划花费3-4个的…

graphrag论文

目录 摘要1 介绍2 图 RAG 方法与流程2.1 源文档 → 文本块2.2 文本块 → 元素实例2.3 元素实例 → 元素摘要2.4 元素摘要 → 图社区2.5 图社区 → 社区摘要2.6 社区摘要 → 社区答案 → 全局答案 3 评估3.1 数据集3.2 查询3.3 条件3.4 指标3.5 配置3.6 结果 4 相关工作4.1 RAG …

深度解析DeepMind乒乓球AI:从AlphaGo到AlphaPingPong的进化之路

引言 谷歌DeepMind在AI研究领域再次取得重大突破&#xff0c;最新推出的乒乓球AI机器人已经能够击败人类选手。这一成就标志着AI从单纯的智力游戏&#xff08;如AlphaGo&#xff09;向物理运动竞技场的转移&#xff0c;充分展示了AI在体育竞技中的潜力。这款AI机器人不仅在击败…

【无标题】Image-to-Image Translation 图像风格迁移中的成对图像拼接代码

引 言 在图像风格迁移任务中&#xff0c;近几年比较火热的Generative Adversarial Nets (GAN)模型以及各种变体深受视觉研究团体的青睐&#xff0c;在具体任务中取得比较不错的实验表现。在有监督图像风格迁移任务迁移中&#xff0c;需要输入给模型成对的图片&#xff08;一个来…

中国气膜技术蓬勃发展:专业公司脱颖而出

气膜技术最早起源于美国&#xff0c;凭借其低造价、快速安装、可移动、可重复使用等独特优势&#xff0c;迅速成为体育、仓储、展览、会议、传媒等行业的首选临时或简易室内空间解决方案。21世纪以来&#xff0c;中国逐步引进并发展了膜结构技术&#xff0c;包括骨架膜、张拉膜…

Spire.PDF for .NET【文档操作】演示:创建 PDF 组合

PDF 作品集是一组文件&#xff0c;其中可以包含文本文档、电子表格、电子邮件、图像、PowerPoint 演示文稿和绘图。尽管 PDF 作品集将不同类型的文件组合成一个单元&#xff0c;但其中的每个文件都保留了其原始格式、分辨率和大小。在本文中&#xff0c;您将学习如何使用Spire.…