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;
		}
	};
相关推荐
6Hzlia17 分钟前
【Hot 100 刷题计划】 LeetCode 287. 寻找重复数 | C++ 数组判环 (快慢指针终极解法)
c++·算法·leetcode
qq_120840937131 分钟前
Three.js 工程向:GLTFLoader 管线、Draco/KTX2 与资源管理
开发语言·javascript·ecmascript
下地种菜小叶38 分钟前
定时任务系统怎么设计?一次讲清任务注册、分布式调度、幂等执行与失败补偿
java·开发语言·数据库·oracle·rabbitmq
csbysj20201 小时前
业务代表模式
开发语言
sghuter1 小时前
AI重塑工程师:未来核心能力全景图
开发语言·perl·composer·symfony
浪客川1 小时前
【百例RUST - 013】泛型
开发语言·后端·rust
Robot_Nav1 小时前
DPMPC-Planner:复杂静态环境与动态障碍物下的无人机实时轨迹规划框架
c++·无人机·mpc
iiiiyu2 小时前
常用API(SimpleDateFormat类 & Calendar类 & JDK8日期 时间 日期时间 & JDK8日期(时区) )
java·大数据·开发语言·数据结构·编程语言
故事和你912 小时前
洛谷-数据结构1-4-图的基本应用2
开发语言·数据结构·算法·深度优先·动态规划·图论
qq_12084093712 小时前
Three.js 工程向:Clock、deltaTime 与固定步长主循环
开发语言·javascript·ecmascript