数据结构: unordered_map与unordered_set

news2024/11/25 23:45:28

目录

1.框架

2.结构

unordered_map

unordered_set

3.对HashTable的修改

更改模板参数

4.增加迭代器

a.结构

b.运算符重载

c.HashTable封装迭代器

d.unordered_map与unordered_set的迭代器


1.框架

1.复用HashTable ~~> 增加模板参数KeyOfT 来获取 Key值

unordered_map传K,V          unordered_set传K

2.增加迭代器: HashNode + HashTable  ~~> ++,[ ]的实现, 普通迭代器构造const迭代器

3.若是要处理自定义类型转换为整型, 在外面写仿函数传给unordered_map或unordered_set

2.结构

unordered_map

	template<class K,class V,class Hash = HashFunc<V>>
	class unordered_map 
	{
		struct MapKeyOfT
		{
			const K& operator()(const pair<K, V>& kv)
			{
				return kv.first;
			}
		};
	public:
		bool insert(const pair<const K, V>& kv) 
		{
			return _ht.Insert(kv);
		}

	private:
		HashBucket::HashTable<K, pair<const K, V>, MapKeyOfT,Hash> _ht;
	};

unordered_set

	template<class K,class Hash = HashFunc<K>>
	class unordered_Set 
	{
	public:
		//仿函数
		struct SetKeyOfT
		{
			const K& operator()(const K& k) 
			{
				return k;
			}
		};

		//接口: insert + erase + find
		bool insert(const K& key) 
		{
			return _ht.Insert(key);
		}

	private:
		HashBucket::HashTable<K, K, SetKeyOfT,Hash> _ht;
	};

3.对HashTable的修改

更改模板参数

1.增加KeyOfT仿函数-->让unordered_map与unordered_set同时复用HashTable

2.增加模板参数K-->区别unordered_map (K,V) 与 unordered_set(K)

~~>所有涉及到取data值的都改为  , 使用仿函数KeyOfT去取 (插入 + 查找  + 删除)

4.增加迭代器

a.结构

	//2.迭代器
	//重载 :  *  ->   ++  == != 
	template<class K,class T,class KeyOfT,class Hash>
	struct __HashIterator 
	{
		typedef HashNode<T> Node;
		typedef HashTable< K, T, KeyOfT, Hash> HT;
		typedef __HashIterator< K, T, KeyOfT, Hash> Self;

		//节点 + 哈希表
		Node* _node;
		const HT* _ht;

		//构造函数
		__HashIterator(Node* node, const HT* ht) 
			:_node(node)
			,_ht(ht)
		{}

		//重载运算符
	};

b.运算符重载

*      ->      ==     !=

		//重载运算符
		T& operator*() { return _node->_data; }
		T* operator->() { return &(_node->_data); }
		bool operator==(const Self& it) { return _node == it._node; }
		bool operator!=(const Self& it) { return _node != it._node; }

++

思路:1.如果下一个节点不为nullptr,返回下一个节点

         2.如果下一个节点为nullptr,找下一个桶

        --先根据节点里面的data,获取key值,来算当前桶的位置

        --找下一个不为空的桶

                        如果这个桶不为空, 把节点给它

                        如果这个桶为空,++hashi

算当前桶的位置: 获取key  +  将非整型数据转换为整型  +  获取哈希桶的个数 + 哈希表

                        ~~>仿函数   +   HashTable提供接口获取 或者  友元

		Self& operator++() 
		{
			//1.如果下一个节点不为nullptr返回下一个节点
			if (_node->_next) 
			{
				_node = _node->_next;
			}
			//2.找下一个不为空的桶
			else 
			{
				//计算当前桶的位置
				Hash hash; KeyOfT kot;
				size_t hashi = hash(kot(_node->_data)) % _ht->GetCapacity();
				vector<Node*> tables = _ht->GetTables();
				++hashi;
				//找到不为空的桶
				while (hashi < _ht->GetCapacity()) 
				{
					if (tables[hashi])
					{
						_node = tables[hashi];
						break;
					}
					else
					{
						++hashi;
					}
				}
				//找完没有下一个节点就返回空指针
				if (hashi == _ht->GetCapacity()) _node = nullptr;
			}
			return *this;
		}
	};

效果:

c.HashTable封装迭代器

begin

思路:

1.找到第一个有元素的桶

		iterator begin() 
		{
			//找第一个有元素的哈希桶
			size_t hashi = 0;
			while (hashi < GetCapacity()) 
			{
				if (_tables[hashi] != nullptr) 
				{
					return iterator(_tables[hashi], this);
				}
				++hashi;
			}
			return iterator(nullptr,this);
		}

end

		iterator end() 
		{
			return iterator(nullptr,this);
		}

d.unordered_map与unordered_set的迭代器

unordered_map与unordered_set的迭代器~~>调用HashTable的迭代器

unordered_map~~> K,V类型允许V被修改~~>const迭代器与普通迭代器

unordered_set~~>  K类型不允许被修改 ~~>const迭代器与普通迭代器都是const迭代器

增加const迭代器与普通迭代器~~> 修改迭代器的模板参数  +  修改HashTable的传参

迭代器的模板参数修改

HashTable传参的修改

unordered_map

unordered_set

提供普通迭代器构造const迭代器

普通对象调用begin函数,返回普通迭代器,但是定义的普通迭代器是const迭代器,会发生隐式类型转换~~>因此需要提供普通迭代器构造const迭代器

[]的实现: a.insert返回类型改为pair<iterator,bool> 

1.调用insert函数~~>若没有这个K值就将其插入到哈希表中

2.返回V

效果:

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

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

相关文章

基于springboot实现致远汽车租赁平台管理系统项目【项目源码+论文说明】

基于springboot实现致远汽车租赁平台系统演示 摘要 首先,论文一开始便是清楚的论述了系统的研究内容。其次,剖析系统需求分析,弄明白“做什么”,分析包括业务分析和业务流程的分析以及用例分析,更进一步明确系统的需求。然后在明白了系统的需求基础上需要进一步地设计系统,主要…

怎么批量获取文件名,并保存到excel?

怎么批量获取文件名&#xff1f;什么叫批量获取文件名&#xff0c;其实也非常好理解&#xff0c;就是面对大量文件是可以一次性的获取所有文件名称&#xff0c;这项技术的应用也是非常常见的&#xff0c;为什么这么说呢&#xff1f;现在很多的文档管理人员或者公司的文员&#…

【AICFD案例教程】汽车外气动-AI加速

AICFD是由天洑软件自主研发的通用智能热流体仿真软件&#xff0c;用于高效解决能源动力、船舶海洋、电子设备和车辆运载等领域复杂的流动和传热问题。软件涵盖了从建模、仿真到结果处理完整仿真分析流程&#xff0c;帮助工业企业建立设计、仿真和优化相结合的一体化流程&#x…

进入网络安全行业有哪些大公司推荐

随着互联网的普及和数字化进程的加速&#xff0c;网络安全问题日益凸显。从个人信息的泄露到国家基础设施的被攻击&#xff0c;网络安全已经不再只是一个技术问题&#xff0c;而是关乎到每个人、每个企业和国家的核心利益。在这场没有硝烟的战争中&#xff0c;一些大公司凭借其…

linux基础指令【上篇】

&#x1f4d9; 作者简介 &#xff1a;RO-BERRY &#x1f4d7; 学习方向&#xff1a;致力于C、C、数据结构、TCP/IP、数据库等等一系列知识 &#x1f4d2; 日后方向 : 偏向于CPP开发以及大数据方向&#xff0c;欢迎各位关注&#xff0c;谢谢各位的支持 引用 01. ls 指令2. pwd命…

IntelliJ Idea 撤回git已经push的操作

最初的样子 现在的样子 解决方案 第一步&#xff0c;commit到本地撤回&#xff1a; 打开提交历史记录&#xff0c;选中回退的版本右键&#xff0c;点击“Reset Current Branch to Here…”,然后选中“Mixed”&#xff0c;点击Reset后&#xff0c;之前commit的代码会在本地显…

定位咨询的价值:企业在市场中如何立足并打造竞争优势?

在激烈的市场竞争中&#xff0c;定位咨询服务显得尤为关键&#xff0c;它既能帮助企业发掘内在优势&#xff0c;又能塑造独特的市场地位&#xff0c;并指导如何持续巩固这一市场地位。 何为定位咨询? 定位咨询&#xff0c;即市场定位咨询&#xff0c;是指咨询公司帮助客户在…

彻底解决Win11锁屏界面黑屏或者图片不变化

问题描述 今天不知道干了啥&#xff0c;一顿操作后&#xff0c;win11的锁屏界面的图片就变成固定的了&#xff0c;原来是有windows聚焦的图片在自动变化的效果&#xff0c;现在没有了。然后就各种搜索求助&#xff0c;第二顿操作之后&#xff0c;锁屏界面彻底变成了黑色&#…

Python从入门到进阶

Python基础入门----Python简介 Python基础入门----安装Python环境&#xff08;Windows、MacOS、CentOS、Ubuntu&#xff09; Python基础入门----Python基础语法&#xff1a;解释器、标识符、关键字、缩进 Python基础入门----Python基本数据类型&#xff1a;数字、字符串、列…

IDEA 编译项目时报错:java: java.lang.OutOfMemoryError:GC overhead limit exceeded解决方法

1.问题简述 在Intellij IDEA下编译Java项目&#xff0c;报错&#xff1a;java.lang.OutOfMemoryError: …(此处忽略) GC overhead limit exceeded 2.问题分析 错误是发生在编译阶段&#xff0c;而不是运行阶段。通过查询相关资料发现&#xff0c; 1.idea编译Java项目使用的虚…

ChromeDriver谷歌浏览器驱动下载安装与使用最新版118/119/120

ChromeDriver谷歌浏览器驱动下载安装与使用最新版118/119/120 1. 确定Chrome版本 我们首先确定自己的Chrome版本 Chrome设置->关于Chrome 可以看到&#xff0c;当前chrome是最新版本&#xff1a;119.0.6045.124&#xff08;正式版本&#xff09; &#xff08;64 位&#…

SOLIDWORKS参数化设计之干涉检查

SOLIDWORKS参数化设计的思路和技巧我们讲过很多了&#xff0c;今天来讲一讲如何在模型完成之后自动执行干涉检查。 SOLIDWORKS软件本身就有干涉检查的功能&#xff0c;在评估选项卡里可以找到该功能&#xff0c;我们这里说的干涉检查指的是静态干涉检查&#xff0c;即模型在静…

WebDAV之π-Disk派盘 + PassStore

大家常用的qq,手机微信,新浪微博等。假如各个网址都设成同样的帐号和登陆密码,一旦某一帐户泄漏了,别的平台上的账户密码都有被撞库攻击的风险。在不一样的站点设定不一样的高韧性登陆密码才算是最安全可靠的确保,殊不知这般繁多的帐户密码是难以记得的。因而,有着一款安…

Echarts示例

一.概念 ECharts&#xff08;Enterprise Charts&#xff09;是百度开源的一个基于JavaScript的可视化图表库。它提供了多种常见的数据可视化图表&#xff0c;包括折线图、柱状图、散点图、饼图、雷达图等等。使用ECharts&#xff0c;用户可以通过简单的配置和接口调用来创建交…

使用Python的requests库采集充电桩LBS位置经纬度信息

目录 一、引言 二、采集数据的流程 1、获取充电桩的URL地址 2、发送HTTP请求获取数据 3、解析数据获取经纬度信息 4、存储数据 三、代码实现 四、注意事项和优化建议 五、充电桩数据的后续利用 六、总结 一、引言 随着电动汽车的普及&#xff0c;充电设施的建设也日…

scss 实用教程

变量 $ 定义变量 $link-color: blue;变量名可以与css中的属性名和选择器名称相同 使用变量 a {color: $link_color; }$highlight-border: 1px solid $link_color;中划线和下划线相互兼容&#xff0c;即中划线声明的变量可以使用下划线的方式引用&#xff0c;反之亦然。 $li…

Power Apps-“编辑“窗体组件

插入一个“编辑”窗体 连接数据源 在该组件的Item函数中编辑筛选符合条件的唯一记录 LookUp(表名,列名值) LookUp参考文档&#xff1a;Filter、Search 和 LookUp 函数&#xff08;包含视频&#xff09; - Power Platform | Microsoft Learn 数据表里的数据就一一对应出现在了组…

邮箱哪家强?哪个牌子邮箱好用

邮箱在国内外使用情况不太一样&#xff0c;国内一般都是工作中需要用邮箱&#xff0c;直接使用公司发的企业邮箱就可以了&#xff0c;个人一般自己需要使用邮箱频率比较少&#xff0c;大多是用来注册其他平台信息&#xff0c;接受验证码、电子发票等等&#xff0c;使用不频繁。…

若依分离版——使用Knife4j 自动生成接口文档

背景&#xff1a; 前后端分离程序&#xff0c;如果需要前端开发人员和后端开发人员配合开发&#xff0c;则需要将接口文档并显性给前端人员 解决办法&#xff1a; 使用knife4j替代若依自带的swagger&#xff0c;因为knife4j是在swagger基础上包装的&#xff0c;Knife4j不仅具…

解析几何@平面上点到直线的距离@点到平面的距离@空间中点到直线的距离

文章目录 平面上点到直线的距离点到平面的距离小结 角平分面问题例 点到直线的距离 平面上点到直线的距离 设坐标平面上有点 P ( x 1 , y 1 ) P(x_1,y_1) P(x1​,y1​)和直线 l : A x B y C 0 l:AxByC0 l:AxByC0, A , B A,B A,B不全为0点 P P P到直线 l l l的的距离的算法推…