06.01_111期_C++_unordermap_unorderset

unordermap 和 unorderset 实现了无序元素的存放,其底层的数据结构是哈希表

哈希表中要让不同类型的数据都能使用除留余数法,

所以在设计哈希表的时候必须要有一个类模板参数可以传入让数据变成整型的函数模板

通过C++的特化,能够让unordermap在插入string 为key值的数据时,

直接走下面的函数,不用再调用的时候专门传入一个仿函数参数

cpp 复制代码
template<>
struct hashFunc<string>
{
	// 由一个字符串生成一个整型数据,需要经过特殊算法的设计,以实现
	// 不同的字符串尽可能对应不同的整型数据
	size_t operator()(const string& key)
	{
		size_t hash = 0;
		for (auto ch : key)
		{
			//至于为什么乘上131,请看BKDR算法的具体推导
			hash *= 131;
			hash += ch;
		}
		return hash;
	}
};
cpp 复制代码
	//  需要注意:__HTIterator的类域中定义_pht的时候,使用了hashTable这个类
	//			  hashTable中返回迭代器的时候,使用了__HTIterator 这个类
	//		针对这个问题有两种解决方式,
	//	方式一:不使用内部类的架构,就需要进行两个操作:
	//		1. 使用以下的前置声明,hashTable这个类以及其对应的模板参数提前,将可以保证编译器不会报错
	//		2. 由于__HTIterator中利用了除留余数法,除留余数法需要使用hashTable的私有成员_tables
	//		   那么可以在hashTable中声明一个友元,将__HTIterator声明为hashTable的友元
	// 
	template<class K, class T, class KeyofT, class Hash>
	class hashTable;

	template<class K, class Ptr, class Ref, class KeyofT, class Hash>
	struct __HTIterator
	{
		typedef hashNode<T> Node;
		typedef __HTIterator<K, T, KeyofT, Hash> Self;
		Node* _node;
		const hashTable* _pht;

	//	// 这么设计迭代器是因为要实现 迭代器的 加加++,
	//	// 只能将哈希桶中的指针数组作为参数传过来
		__HTIterator(Node* node, const hashTable* pht)
			:_node(node)
			,_pht(pht)
		{}

		Ref operator*()
		{
			return _node->_data;
		}

		Ptr operator->()
		{
			return &(_node->_data);
		}

		Self& operator++()
		{
			if (_node->_next)
			{
				//当前桶没走完,取当前桶的下一个节点
				_node = _node->_next;
			}
			else
			{
				//当前桶走完,取当前桶的下一个节点
				KeyofT kot;
				Hash hs;
				size_t i = hs(kot(_node->_data)) % _pht->_tables.size();
				++i;
				for (; i < _pht->_tables.size(); i++)
				{
					if (_pht->_tables[i])
					{
						break;
					}
				}

				//针对如果当前vector容器走完的情况,令_node 赋值为nullptr
				if (i == _pht->_tables.size())
				{
					_node = nullptr;
				}
				else
				{
					_node = _pht->_tables[i];
				}
			}
			return *this;
		}

		bool operator!=(const Self& s)
		{
			return _node != s._node;
		}
	};
相关推荐
xlxxy_30 分钟前
外部系统调用SAP接口遇到的一些报错
开发语言·数据库·sap·abap
八角.。34 分钟前
方法参数与Debug按键
java·开发语言·jvm
郝亚军1 小时前
FE1.1S-BQFN24BT可以指定IP端口吗?
开发语言·php
阿里嘎多学长1 小时前
2026-08-04 GitHub 热点项目精选
开发语言·程序员·github·代码托管
晴天161 小时前
Rust 快速入门 (从 JavaScript 开发者视角)-Day09
开发语言·javascript·rust
步行cgn2 小时前
carList.forEach(System.out::println)
java·开发语言·mybatis
进击的程序猿~2 小时前
Go 内存分配与垃圾回收源码深度学习手册
开发语言·后端·golang
June`2 小时前
warp shuffle指令
c++·人工智能·算法·cuda
geovindu2 小时前
go:Bit Operation Algorithm
开发语言·后端·算法·golang·位运算法
乱七八糟的屋子2 小时前
【C++数值计算】NumCpp超详细入门教程(纯正Numpy语法、零学习成本、C++首选科学计算库、性能压测对比)
c++·数值计算·numpy·高性能计算·科学计算·ndarray