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;
		}
	};
相关推荐
冷崖1 小时前
原子锁操作
c++·后端
旖旎夜光5 小时前
C++(17)
c++·学习
Larry_Yanan6 小时前
Qt多进程(三)QLocalSocket
开发语言·c++·qt·ui
醒过来摸鱼6 小时前
Java classloader
java·开发语言·python
superman超哥6 小时前
仓颉语言中元组的使用:深度剖析与工程实践
c语言·开发语言·c++·python·仓颉
小鸡吃米…6 小时前
Python - 继承
开发语言·python
JIngJaneIL6 小时前
基于java+ vue农产投入线上管理系统(源码+数据库+文档)
java·开发语言·前端·数据库·vue.js·spring boot
祁思妙想6 小时前
Python中的FastAPI框架的设计特点和性能优势
开发语言·python·fastapi
唐装鼠6 小时前
rust自动调用Deref(deepseek)
开发语言·算法·rust
Lucas555555557 小时前
现代C++四十不惑:AI时代系统软件的基石与新征程
开发语言·c++·人工智能