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;
		}
	};
相关推荐
雪的季节22 分钟前
企业级 Qt 全功能项目
开发语言·数据库·qt
代龙涛1 小时前
WordPress page.php 页面模板与自定义模板使用方法
android·开发语言·php
bigfootyazi1 小时前
python爬虫-基本库-urllib库(常用速查)
开发语言·爬虫·python
belong_my_offer2 小时前
认识到精通函数
开发语言·python
guygg882 小时前
最大相关-最小冗余(mRMR)特征选择 MATLAB 实现
开发语言·matlab
郭涤生2 小时前
C++ 高性能编程最佳实践清单
开发语言·c++
烛衔溟2 小时前
TypeScript 类的静态成员与静态方法
开发语言·javascript·typescript
Nile2 小时前
解密Palantir系列一:4. Ontology 不是哲学
开发语言·前端·javascript
罗超驿3 小时前
15.JavaScript 函数与作用域完全指南:语法、参数、表达式与作用域链实战
开发语言·前端·javascript
.千余3 小时前
【C++】C++类与对象2:C++构造函数、运算符重载与流输入输出全面解析
c语言·开发语言·前端·c++·经验分享