目录
unordered系列关联式容器
哈希的简介
哈希表闭散列实现
哈希表开散列实现
用哈希表来封装map和set
位图
布隆过滤器与哈希切割
全部代码
unordered系列关联式容器
unordered系列关联式容器有四种,这里主要对unordered_map和unordered_set这两种容器进行介绍
unordered_map
unordered_map是存储<key, value>键值对的关联式容器,其允许通过keys快速的索引到与其对应的value
在内部,unordered_map没有对<kye, value>按照任何特定的顺序排序
unordered_map容器通过key访问单个元素要比map快,但它通常在遍历元素子集的范围迭代方面效率较低
unordered_maps实现了直接访问操作符(operator[]),它允许使用key作为参数直接访问value
unordered_set
unordered_set和unordered_map在性质上差不多,因为底层结构是一致的,都是哈希结构,区别在与,unordered_set不支持[],因为它存储的是key与value相同,所以无需支持[]
哈希的简介
概念
如果构造一种存储结构,通过某种函数(hashFunc)使元素的存储位置与它的关键码之间能够建立一一映射的关系,那么在查找时通过该函数可以很快找到该元素
哈希函数有多种,这里采用除留余数法
哈希冲突
比如14和4取模后都是4,而4对应的位置只能存储一个数字,那么就出现了哈希冲突,而解决哈希冲突的常见两种方法有闭散列和开散列
哈希表闭散列实现
闭散列:也叫开放定址法,当发生哈希冲突时,如果哈希表未被装满,说明在哈希表中必然还有空位置,那么可以把key存放到冲突位置中的“下一个” 空位置中去
寻找下一空位置有线性探测和二次探测两种
线性探测
从发生冲突的位置开始,依次向后探测,直到寻找到下一个空位置为止

二次探测
从发生冲突的位置开始,跨越探测,直到寻找到下一个空位置为止

index是哈希表的下标
首先因为有闭散列和开散列两种,所以采用命名空间的形式来防止命名冲突

 
然后定义一个枚举类型,用来判断该下标的空间的状态,是存在数据,还是删除过数据,或者没有数据,便于插入,删除,及查找数据

封装节点,开始必然为每个下标所在的空间必然为空状态,所以初始化为空状态
 
因为要是除留取余法,必然要是整数,所以还需要借助仿函数来实现
内置类型

string类型
string类型转整形,可以将字符串的每个字母的ASCII码值加起来,但要是只是顺序不同,那总数也会相同,出现哈希冲突,为了尽量减少哈希冲突,就有了下图的方法,其中31是累乘因子
string类型有下列两种写法,任选其一即可


对于其它自定义类型,比如日期,则按照特定方式取整即可
哈希表同样采用模板的形式实现,另外私有成员有中的_n是有效数据个数,便于后续插入数据扩容使用

 
查找数据
如果表为空,则直接返回nullptr即可

首先用待查找的key模表的长度取模作为待查找的初始下标,然后一直往后查找,同时往后走时,最后别忘了再取模一次,因为可能会存在初始下标空间的前面空间,找不到时,则直接返回nullptr
 删除数据
删除数据
首先先查找数据,找到数据了有效数据就减少一个,然后将那个节点的状态置为删除状态,删除成功返回true即可,没找到就表示删除失败,返回false

插入数据
首先先查找数据,如果存在,就表示待插入的数据已经有了,所以无需再插入,返回false即可

根据有效数据个数,得到负载因子,如果负载因子大于等于0.7则表示需要扩容了,初始没有空间时,也一样需要扩容
负载因子越小,冲突概率越低,效率越高,空间浪费越多
负载因子越大,冲突概率越高,效率越低,空间浪费越少

如果是初始时则开10个空间,其它情况则直接开原来的2倍空间
 
创建一个新表,开辟新空间大小的空间,再将其数据拷贝到新表,然后将新表对象中的vector成员与this对象中的vector成员交换即可

如果不需要开辟新空间
则先将key取模,找到对应的下标,如果有空间,则直接插入数据,没有,则继续往后面找,与find()类似,最后有效数据+1,返回true即可

闭散列最大的缺陷就是空间利用率比较低,这也是哈希的缺陷
哈希表开散列实现
概念
开散列法又叫链地址法(开链法),首先对关键码集合用散列函数计算散列地址,具有相同地址的关键码归于同一子集合,每一个子集合称为一个桶,各个桶中的元素通过一个单链表链接起来,各链表的头结点存储在哈希表中,开散列中每个桶中放的都是发生哈希冲突的元素,如下图

封装节点,其实就是单链表的节点封装

 
私有成员与闭散列一致,同时,还是采用除留去余法,所以会用到仿函数,与上面闭散列一致

查找数据
如果哈希表为空,则直接返回nullptr

找到待查找的数据节点的下标,以及声明一个局部变量来保存这条链的头节点

从头开始往后找,找到了返回节点地址,没找到返回nullptr

删除数据
如果哈希表为空,返回false,表示删除失败

找到待删除数据节点的那条链的头节点

如果找到了,则分为两种情况,如果就是头节点,那就直接头删,否则就中间删除
 
如果没找到,则继续往后面找,找不到则返回false,表示删除失败

插入数据
首先先查找数据,如果存在,就表示待插入的数据已经有了,所以无需再插入,返回false即可
 
如果负载因子等于1时,则需要扩容,初始开空间时开10个空间,其余情况开原来的2倍空间

然后将原表的数据按头插拷贝到新表,将原表每条链的表头置空,最后再交换this对象的vector成员与新表的vector成员即可

如果不需要扩容,则直接头插,然后将有效数据个数+1,再返回true即可

为了减少哈希冲突,每次扩容后的空间大小都为素数

 
  
用哈希表来封装map和set
改善哈希表
因为既要封装map,又要封装set,所以将数据类型从pair类型变为了T类型

迭代器
因为会用到哈希表,所以提前声明一下

因为要封装map和set,所以多加了一个模板参数KeyOfT,采用了仿函数



因为map和set存储的数据不同,一个是pair<key,value>,一个是key所以对*和对->都要重载

判断相不相等,比较的是节点的地址相不相等

重载++运算符
如果这条链上还有节点,即没有遇到nullptr,则直接往后走即可

如果为nullptr,则从哈希表的下一个元素开始找,比如下图,走完11后,则继续往后面走,下一个元素表头为空,所以就走到了13,不为nullptr,则跳出循环


 
如果是循环自动结束的,即走完整个哈希表了,则直接置nullptr即可
 
如果是break出来的,则直接返回到那个节点,比如上述所说的13
 
拷贝构造
别忘了写一个默认构造函数,因为有了拷贝构造之后,编译器不会默认生成了

这里采用的是头插法,所以顺序会有变化

重载赋值运算符
将实参传给形参时会有一次拷贝构造,所以只需将this对象的两个成员与形参的交换即可

析构函数
从哈希表第一个元素开始销毁节点,直到走完哈希表结束

初始节点
如果哈希表第一个元素的头节点不为nullptr,则它就是初始节点,否则直接返回nullptr的迭代器

结尾节点,即nullptr

重载[]运算符
[]可查找value,也可修改或插入

位图
位图的作用:数据是否在给定的整形数据中,结果是在或者不在,刚好是两种状态,那么可以使用一个二进制比特位来代表数据是否存在的信息,如果二进制比特位为1,代表存在,为0代表不存在,比如在一堆数据中找5在不在,数据很多时,可以开辟整形最大值那么大的以bit为单位的空间,然后一个整数对应一个比特位,如果5对应的比特位是1,那就在这堆数据中,是0就不在
1byte=8bit,所以开空间数如下图


将某个bit位置为1

将某个bit位置为0

检查某个bit位是否为1
0为假,非0为真

位图:节省空间,效率高,但只能处理整数
布隆过滤器与哈希切割
概念
布隆过滤器是由布隆在1970年提出的 一种紧凑型的、比较巧妙的概率型数据结构,特点是高效地插入和查询,可以用来告诉你 “某样东西一定不存在或者可能存在”,它是用多个哈希函数,将一个数据映射到位图结构中。既可以提升查询效率,也可以节省大量的内存空间
作用:用来解决字符串,自定义类型对象在不在的问题
如果采用将字符串转整数,即将字符串的各个字符加起来取模作为下标,那就可能会存在哈希冲突,比如下图中eat和ate

这种方式,判断不在是准确的,比如eat和ate那个位置的比特位为0,则eat肯定不在,只是判断在会存在误判
解决方式
将一个元素用多个哈希函数映射到一个位图中,比如ate,只要三个种有一个bit位为0,则就表示ate不在,降低了误判率

这里以哈希函数中三个不同的哈希函数为例 模板参数
模板参数
  
   - 
    
     
    
    
     
      //hashTable-副本
     
    
- 
    
     
    
    
     
      #pragma once
     
    
- 
    
     
    
    
     
      #include<vector>
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      template<
      class 
      K>
     
    
- 
    
     
    
    
     
      struct 
      Hash
     
    
- 
    
     
    
    
     
      {
     
    
- 
    
     
    
    
     	
      size_t operator()(const K& key)
     
    
- 
    
     
    
    
     
      	{
     
    
- 
    
     
    
    
     		
      return key;
     
    
- 
    
     
    
    
     
      	}
     
    
- 
    
     
    
    
     
      };
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      //特化
     
    
- 
    
     
    
    
     
      template<>
     
    
- 
    
     
    
    
     
      struct 
      Hash< string >
     
    
- 
    
     
    
    
     
      {
     
    
- 
    
     
    
    
     	
      size_t operator()(const string& s)
     
    
- 
    
     
    
    
     
      	{
     
    
- 
    
     
    
    
     		
      //BKDR
     
    
- 
    
     
    
    
     		
      size_t value = 
      0;
     
    
- 
    
     
    
    
     		
      for (
      auto ch : s)
     
    
- 
    
     
    
    
     
      		{
     
    
- 
    
     
    
    
     
      			value *= 
      31;
     
    
- 
    
     
    
    
     
      			value += ch;
     
    
- 
    
     
    
    
     
      		}
     
    
- 
    
     
    
    
     		
      return value;
     
    
- 
    
     
    
    
     
      	}
     
    
- 
    
     
    
    
     
      };
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      namespace CloseHash
     
    
- 
    
     
    
    
     
      {
     
    
- 
    
     
    
    
     	
      enum 
      Status
     
    
- 
    
     
    
    
     
      	{
     
    
- 
    
     
    
    
     
      		EXIST,
     
    
- 
    
     
    
    
     
      		EMPTY,
     
    
- 
    
     
    
    
     
      		DELETE
     
    
- 
    
     
    
    
     
      	};
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     	
      template<
      class 
      K,
      class 
      V>
     
    
- 
    
     
    
    
     	
      struct 
      HashData
     
    
- 
    
     
    
    
     
      	{
     
    
- 
    
     
    
    
     
      		pair<K, V> _kv;
     
    
- 
    
     
    
    
     
      		Status _status = EMPTY;
     
    
- 
    
     
    
    
     
      	};
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     	
      struct 
      HashStr
     
    
- 
    
     
    
    
     
      	{
     
    
- 
    
     
    
    
     		
      size_t operator()(const string& s)
     
    
- 
    
     
    
    
     
      		{
     
    
- 
    
     
    
    
     			
      //BKDR
     
    
- 
    
     
    
    
     			
      size_t value = 
      0;
     
    
- 
    
     
    
    
     			
      for (
      auto ch : s)
     
    
- 
    
     
    
    
     
      			{
     
    
- 
    
     
    
    
     
      				value *= 
      31;
     
    
- 
    
     
    
    
     
      				value += ch;
     
    
- 
    
     
    
    
     
      			}
     
    
- 
    
     
    
    
     			
      return value;
     
    
- 
    
     
    
    
     
      		}
     
    
- 
    
     
    
    
     
      	};
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     	
      template<
      class 
      K,
      class 
      V,
      class 
      HashFunc = Hash<K>>
     
    
- 
    
     
    
    
     	
      class HashTable
     
    
- 
    
     
    
    
     
      	{
     
    
- 
    
     
    
    
     	
      public:
     
    
- 
    
     
    
    
     		
      bool 
      Erase(
      const K& key)
     
    
- 
    
     
    
    
     
      		{
     
    
- 
    
     
    
    
     
      			HashData<K, V>* ret = 
      Find(key);
     
    
- 
    
     
    
    
     			
      if (ret == 
      nullptr)
     
    
- 
    
     
    
    
     
      			{
     
    
- 
    
     
    
    
     				
      return 
      false;
     
    
- 
    
     
    
    
     
      			}
     
    
- 
    
     
    
    
     			
      else
     
    
- 
    
     
    
    
     
      			{
     
    
- 
    
     
    
    
     
      				--_n;
     
    
- 
    
     
    
    
     
      				ret->_status = DELETE;
     
    
- 
    
     
    
    
     				
      return 
      true;
     
    
- 
    
     
    
    
     
      			}
     
    
- 
    
     
    
    
     
      		}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     		
      HashData<K, V>* Find(const K& key)
     
    
- 
    
     
    
    
     
      		{
     
    
- 
    
     
    
    
     			
      if (_tables.
      size() == 
      0)
     
    
- 
    
     
    
    
     
      			{
     
    
- 
    
     
    
    
     				
      return 
      nullptr;
     
    
- 
    
     
    
    
     
      			}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      			HashFunc hf;
     
    
- 
    
     
    
    
     			
      size_t start = 
      hf(key) % _tables.
      size();
     
    
- 
    
     
    
    
     			
      size_t i = 
      0;
     
    
- 
    
     
    
    
     			
      size_t index = start;
     
    
- 
    
     
    
    
     			
      //线性探测 or 二次探测
     
    
- 
    
     
    
    
     			
      while (_tables[index]._status != EMPTY)
     
    
- 
    
     
    
    
     
      			{
     
    
- 
    
     
    
    
     				
      if (_tables[index]._kv.first == key && _tables[index]._status == EXIST)
     
    
- 
    
     
    
    
     
      				{
     
    
- 
    
     
    
    
     					
      return &_tables[index];
     
    
- 
    
     
    
    
     
      				}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      				++i;
     
    
- 
    
     
    
    
     				
      //index = start + i*i;
     
    
- 
    
     
    
    
     
      				index = start + i;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      				index %= _tables.
      size();
     
    
- 
    
     
    
    
     
      			}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     			
      return 
      nullptr;
     
    
- 
    
     
    
    
     
      		}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     		
      bool Insert(const pair<K, V>& kv)
     
    
- 
    
     
    
    
     
      		{
     
    
- 
    
     
    
    
     
      			HashData<K, V>* ret = 
      Find(kv.first);
     
    
- 
    
     
    
    
     			
      if (ret)
     
    
- 
    
     
    
    
     
      			{
     
    
- 
    
     
    
    
     				
      return 
      false;
     
    
- 
    
     
    
    
     
      			}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     			
      //负载因子到0.7,就扩容
     
    
- 
    
     
    
    
     			
      //负载因子越小,冲突概率越低,效率越高,空间浪费越多
     
    
- 
    
     
    
    
     			
      //负载因子越大,冲突概率越高,效率越低,空间浪费越少
     
    
- 
    
     
    
    
     			
      if (_tables.
      size() == 
      0 || _n * 
      10 / _tables.
      size() >= 
      7)
     
    
- 
    
     
    
    
     
      			{
     
    
- 
    
     
    
    
     				
      //扩容
     
    
- 
    
     
    
    
     				
      size_t newSize = _tables.
      size() == 
      0 ? 
      10 : _tables.
      size() * 
      2;
     
    
- 
    
     
    
    
     				
      //vector<HashData<K,V>> newTables;
     
    
- 
    
     
    
    
     				
      //newTables.resize(newSize);
     
    
- 
    
     
    
    
     				
      //遍历原表,把原表中的数据,重新按newSize映射到新表
     
    
- 
    
     
    
    
     				
      //for(size_t i = 0;i < _tables.size();++i)
     
    
- 
    
     
    
    
     				
      //{
     
    
- 
    
     
    
    
     					
      //
     
    
- 
    
     
    
    
     				
      //}
     
    
- 
    
     
    
    
     				
      //_tables.swap(newTables);
     
    
- 
    
     
    
    
     
      				HashTable<K, V, HashFunc> newHT;
     
    
- 
    
     
    
    
     
      				newHT._tables.
      resize(newSize);
     
    
- 
    
     
    
    
     				
      for (
      size_t i = 
      0; i < _tables.
      size(); ++i)
     
    
- 
    
     
    
    
     
      				{
     
    
- 
    
     
    
    
     					
      if (_tables[i]._status == EXIST)
     
    
- 
    
     
    
    
     
      					{
     
    
- 
    
     
    
    
     
      						newHT.
      Insert(_tables[i]._kv);
     
    
- 
    
     
    
    
     
      				    }
     
    
- 
    
     
    
    
     
      				}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      				_tables.
      swap(newHT._tables);
     
    
- 
    
     
    
    
     
      			}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      			HashFunc hf;
     
    
- 
    
     
    
    
     			
      size_t start = 
      hf(kv.first) % _tables.
      size();
     
    
- 
    
     
    
    
     			
      size_t i = 
      0;
     
    
- 
    
     
    
    
     			
      size_t index = start;
     
    
- 
    
     
    
    
     			
      //线性探测 or 二次探测
     
    
- 
    
     
    
    
     			
      while (_tables[index]._status == EXIST)
     
    
- 
    
     
    
    
     
      			{
     
    
- 
    
     
    
    
     
      				++i;
     
    
- 
    
     
    
    
     				
      //index = start + i * i;
     
    
- 
    
     
    
    
     
      				index = start + i;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      				index %= _tables.
      size();
     
    
- 
    
     
    
    
     
      			}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      			_tables[index]._kv = kv;
     
    
- 
    
     
    
    
     
      			_tables[index]._status = EXIST;
     
    
- 
    
     
    
    
     
      			++_n;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     			
      return 
      true;
     
    
- 
    
     
    
    
     
      		}
     
    
- 
    
     
    
    
     	
      private:
     
    
- 
    
     
    
    
     
      		vector<HashData<K, V>> _tables;
     
    
- 
    
     
    
    
     		
      size_t _n = 
      0;
      //有效数据个数
     
    
- 
    
     
    
    
     
      	};
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     	
      void TestHashTable1()
     
    
- 
    
     
    
    
     
      	{
     
    
- 
    
     
    
    
     		
      //HashTable<int,int,Hash<int>> ht;
     
    
- 
    
     
    
    
     
      		HashTable<
      int, 
      int> ht;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     		
      int a[] = { 
      2,
      12,
      22,
      32,
      42,
      52,
      62 };
     
    
- 
    
     
    
    
     		
      for (
      auto e : a)
     
    
- 
    
     
    
    
     
      		{
     
    
- 
    
     
    
    
     
      			ht.
      Insert(
      make_pair(e, e));
     
    
- 
    
     
    
    
     
      		}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      		ht.
      Insert(
      make_pair(
      72, 
      72));
     
    
- 
    
     
    
    
     
      		ht.
      Insert(
      make_pair(
      72, 
      72));
     
    
- 
    
     
    
    
     
      		ht.
      Insert(
      make_pair(
      -1, 
      -1));
     
    
- 
    
     
    
    
     
      		ht.
      Insert(
      make_pair(
      -999, 
      -999));
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      		Hash<
      int> hs;
     
    
- 
    
     
    
    
     
      		cout << 
      hs(
      9) << endl;
     
    
- 
    
     
    
    
     
      		cout << 
      hs(
      -9) << endl;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      		cout << ht.
      Find(
      12) << endl;
     
    
- 
    
     
    
    
     
      		ht.
      Erase(
      12);
     
    
- 
    
     
    
    
     
      		cout << ht.
      Find(
      12) << endl;
     
    
- 
    
     
    
    
     
      	}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     	
      struct 
      Date
     
    
- 
    
     
    
    
     
      	{
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      	};
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     	
      struct 
      HashDate
     
    
- 
    
     
    
    
     
      	{
     
    
- 
    
     
    
    
     		
      size_t operator()(const Date& d)
     
    
- 
    
     
    
    
     
      		{
     
    
- 
    
     
    
    
     			
      //...
     
    
- 
    
     
    
    
     
      		}
     
    
- 
    
     
    
    
     
      	};
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     	
      void TestHashTable2()
     
    
- 
    
     
    
    
     
      	{
     
    
- 
    
     
    
    
     
      		HashStr hs;
     
    
- 
    
     
    
    
     
      		cout << 
      hs(
      "sort") << endl;
     
    
- 
    
     
    
    
     
      		cout << 
      hs(
      "insert") << endl;
     
    
- 
    
     
    
    
     
      		cout << 
      hs(
      "eat") << endl;
     
    
- 
    
     
    
    
     
      		cout << 
      hs(
      "ate") << endl;
     
    
- 
    
     
    
    
     
      		cout << 
      hs(
      "abcd") << endl;
     
    
- 
    
     
    
    
     
      		cout << 
      hs(
      "aadd") << endl;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      		HashTable<string, string> ht;
     
    
- 
    
     
    
    
     
      		ht.
      Insert(
      make_pair(
      "sort", 
      "排序"));
     
    
- 
    
     
    
    
     
      		ht.
      Insert(
      make_pair(
      "string", 
      "字符串"));
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     		
      //当key是一个定义类型时,需要配置一个仿函数,将key转成整形
     
    
- 
    
     
    
    
     
      		HashTable<Date, string, HashDate> htds;
     
    
- 
    
     
    
    
     
      	}
     
    
- 
    
     
    
    
     
      }
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      namespace LinkHash
     
    
- 
    
     
    
    
     
      {
     
    
- 
    
     
    
    
     	
      template<
      class 
      K,
      class 
      V>
     
    
- 
    
     
    
    
     	
      struct 
      HashNode
     
    
- 
    
     
    
    
     
      	{
     
    
- 
    
     
    
    
     
      		pair<K, V> _kv;
     
    
- 
    
     
    
    
     
      		HashNode<K, V>* _next;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     		
      HashNode(
      const pair<K, V>& kv):_kv(kv),_next(
      nullptr)
     
    
- 
    
     
    
    
     
      		{}
     
    
- 
    
     
    
    
     
      	};
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     	
      template<
      class 
      K,
      class 
      V,
      class 
      HashFunc = Hash<K>>
     
    
- 
    
     
    
    
     	
      class HashTable
     
    
- 
    
     
    
    
     
      	{
     
    
- 
    
     
    
    
     		
      typedef HashNode<K, V> Node;
     
    
- 
    
     
    
    
     	
      public:
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     		
      bool Erase(const K& key)
     
    
- 
    
     
    
    
     
      		{
     
    
- 
    
     
    
    
     			
      if (_tables.
      empty())
     
    
- 
    
     
    
    
     
      			{
     
    
- 
    
     
    
    
     				
      return 
      false;
     
    
- 
    
     
    
    
     
      			}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      			HashFunc hf;
     
    
- 
    
     
    
    
     			
      size_t index = 
      hf(key) % _tables.
      size();
     
    
- 
    
     
    
    
     
      			Node* prev = 
      nullptr;
     
    
- 
    
     
    
    
     
      			Node* cur = _tables[index];
     
    
- 
    
     
    
    
     			
      while (cur)
     
    
- 
    
     
    
    
     
      			{
     
    
- 
    
     
    
    
     				
      if (cur->_kv.first == key)
     
    
- 
    
     
    
    
     
      				{
     
    
- 
    
     
    
    
     					
      if (prev == 
      nullptr) 
      //头删
     
    
- 
    
     
    
    
     
      					{
     
    
- 
    
     
    
    
     
      						_tables[index] = cur->_next;
     
    
- 
    
     
    
    
     
      					}
     
    
- 
    
     
    
    
     					
      else 
      //中间删除
     
    
- 
    
     
    
    
     
      					{
     
    
- 
    
     
    
    
     
      						prev->_next = cur->_next;
     
    
- 
    
     
    
    
     
      					}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      					--_n;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     					
      delete cur;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     					
      return 
      true;
     
    
- 
    
     
    
    
     
      				}
     
    
- 
    
     
    
    
     				
      else
     
    
- 
    
     
    
    
     
      				{
     
    
- 
    
     
    
    
     
      					prev = cur;
     
    
- 
    
     
    
    
     
      					cur = cur->_next;
     
    
- 
    
     
    
    
     
      				}
     
    
- 
    
     
    
    
     
      			}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     			
      return 
      false;
     
    
- 
    
     
    
    
     
      		}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     		
      Node* Find(const K& key)
     
    
- 
    
     
    
    
     
      		{
     
    
- 
    
     
    
    
     			
      if (_tables.
      empty())
     
    
- 
    
     
    
    
     
      			{
     
    
- 
    
     
    
    
     				
      return 
      nullptr;
     
    
- 
    
     
    
    
     
      			}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      			HashFunc hf;
     
    
- 
    
     
    
    
     			
      size_t index = 
      hf(key) % _tables.
      size();
     
    
- 
    
     
    
    
     
      			Node* cur = _tables[index];
     
    
- 
    
     
    
    
     			
      while (cur)
     
    
- 
    
     
    
    
     
      			{
     
    
- 
    
     
    
    
     				
      if (cur->_kv.first == key)
     
    
- 
    
     
    
    
     
      				{
     
    
- 
    
     
    
    
     					
      return cur;
     
    
- 
    
     
    
    
     
      				}
     
    
- 
    
     
    
    
     				
      else
     
    
- 
    
     
    
    
     
      				{
     
    
- 
    
     
    
    
     
      					cur = cur->_next;
     
    
- 
    
     
    
    
     
      				}
     
    
- 
    
     
    
    
     
      			}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     			
      return 
      nullptr;
     
    
- 
    
     
    
    
     
      		}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     		
      bool Insert(const pair<K, V>& kv)
     
    
- 
    
     
    
    
     
      		{
     
    
- 
    
     
    
    
     
      			Node* ret = 
      Find(kv.first);
     
    
- 
    
     
    
    
     			
      if (ret)
     
    
- 
    
     
    
    
     				
      return 
      false;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      			HashFunc hf;
     
    
- 
    
     
    
    
     			
      if (_n == _tables.
      size())
     
    
- 
    
     
    
    
     
      			{
     
    
- 
    
     
    
    
     				
      size_t newSize = _tables.
      size() == 
      0 ? 
      10 : _tables.
      size() * 
      2;
     
    
- 
    
     
    
    
     				
      //...
     
    
- 
    
     
    
    
     
      				vector<Node*> newTables;
     
    
- 
    
     
    
    
     
      				newTables.
      resize(newSize);
     
    
- 
    
     
    
    
     				
      for (
      size_t i = 
      0; i < _tables.
      size(); ++i)
     
    
- 
    
     
    
    
     
      				{
     
    
- 
    
     
    
    
     
      					Node* cur = _tables[i];
     
    
- 
    
     
    
    
     					
      while (cur)
     
    
- 
    
     
    
    
     
      					{
     
    
- 
    
     
    
    
     
      						Node* next = cur->_next;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     						
      size_t index = 
      hf(cur->_kv.first) % newTables.
      size();
     
    
- 
    
     
    
    
     						
      //头插
     
    
- 
    
     
    
    
     
      						cur->_next = newTables[index];
     
    
- 
    
     
    
    
     
      						newTables[index] = cur;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      						cur = next;
     
    
- 
    
     
    
    
     
      					}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      					_tables[i] = 
      nullptr;
     
    
- 
    
     
    
    
     
      				}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      				_tables.
      swap(newTables);
     
    
- 
    
     
    
    
     
      			}
     
    
- 
    
     
    
    
     			
      size_t index = 
      hf(kv.first) % _tables.
      size();
     
    
- 
    
     
    
    
     
      			Node* newnode = 
      new 
      Node(kv);
     
    
- 
    
     
    
    
     			
      //头插
     
    
- 
    
     
    
    
     
      			newnode->_next = _tables[index];
     
    
- 
    
     
    
    
     
      			_tables[index] = newnode;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      			++_n;
     
    
- 
    
     
    
    
     			
      return 
      true;
     
    
- 
    
     
    
    
     
      		}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     	
      private:
     
    
- 
    
     
    
    
     		
      /*struct Data
     
    
- 
    
     
    
    
     
       {
     
    
- 
    
     
    
    
     
       forward_list<T> _list;
     
    
- 
    
     
    
    
     
       set<T> _rbtree;
     
    
- 
    
     
    
    
     
       size_t len;
     
    
- 
    
     
    
    
     
       };
     
    
- 
    
     
    
    
     
       vector<Data> _table;*/
     
    
- 
    
     
    
    
     
      		vector<Node*> _tables;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     		
      size_t _n = 
      0;
      //有效数据的个数
     
    
- 
    
     
    
    
     
      	};
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     	
      void TestHashTable()
     
    
- 
    
     
    
    
     
      	{
     
    
- 
    
     
    
    
     		
      int a[] = { 
      4,
      24,
      14,
      7,
      37,
      27,
      57,
      67,
      34,
      14,
      54 };
     
    
- 
    
     
    
    
     
      		HashTable<
      int, 
      int> ht;
     
    
- 
    
     
    
    
     		
      for (
      auto e : a)
     
    
- 
    
     
    
    
     
      		{
     
    
- 
    
     
    
    
     
      			ht.
      Insert(
      make_pair(e, e));
     
    
- 
    
     
    
    
     
      		}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      		ht.
      Insert(
      make_pair(
      84, 
      84));
     
    
- 
    
     
    
    
     
      	}
     
    
- 
    
     
    
    
     
      };
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      //hashTable
     
    
- 
    
     
    
    
     
      #pragma once
     
    
- 
    
     
    
    
     
      #include<vector>
     
    
- 
    
     
    
    
     
      #include<string>
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      template<
      class 
      K>
     
    
- 
    
     
    
    
     
      struct 
      Hash
     
    
- 
    
     
    
    
     
      {
     
    
- 
    
     
    
    
     	
      size_t operator()(const K& key)
     
    
- 
    
     
    
    
     
      	{
     
    
- 
    
     
    
    
     		
      return key;
     
    
- 
    
     
    
    
     
      	}
     
    
- 
    
     
    
    
     
      };
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      //特化
     
    
- 
    
     
    
    
     
      template<>
     
    
- 
    
     
    
    
     
      struct 
      Hash< string >
     
    
- 
    
     
    
    
     
      {
     
    
- 
    
     
    
    
     	
      size_t operator()(const string& s)
     
    
- 
    
     
    
    
     
      	{
     
    
- 
    
     
    
    
     		
      //BKDR
     
    
- 
    
     
    
    
     		
      size_t value = 
      0;
     
    
- 
    
     
    
    
     		
      for (
      auto ch : s)
     
    
- 
    
     
    
    
     
      		{
     
    
- 
    
     
    
    
     
      			value *= 
      31;
     
    
- 
    
     
    
    
     
      			value += ch;
     
    
- 
    
     
    
    
     
      		}
     
    
- 
    
     
    
    
     		
      return value;
     
    
- 
    
     
    
    
     
      	}
     
    
- 
    
     
    
    
     
      };
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      namespace CloseHash
     
    
- 
    
     
    
    
     
      {
     
    
- 
    
     
    
    
     	
      enum 
      Status
     
    
- 
    
     
    
    
     
      	{
     
    
- 
    
     
    
    
     
      		EXIST,
     
    
- 
    
     
    
    
     
      		EMPTY,
     
    
- 
    
     
    
    
     
      		DELETE
     
    
- 
    
     
    
    
     
      	};
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     	
      template<
      class 
      K, 
      class 
      V>
     
    
- 
    
     
    
    
     	
      struct 
      HashData
     
    
- 
    
     
    
    
     
      	{
     
    
- 
    
     
    
    
     
      		pair<K, V> _kv;
     
    
- 
    
     
    
    
     
      		Status _status = EMPTY;
     
    
- 
    
     
    
    
     
      	};
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     	
      //struct HashStr
     
    
- 
    
     
    
    
     	
      //{
     
    
- 
    
     
    
    
     	
      // size_t operator()(const string& s)
     
    
- 
    
     
    
    
     	
      // {
     
    
- 
    
     
    
    
     	
      // //BKDR
     
    
- 
    
     
    
    
     	
      // size_t value = 0;
     
    
- 
    
     
    
    
     	
      // for (auto ch : s)
     
    
- 
    
     
    
    
     	
      // {
     
    
- 
    
     
    
    
     	
      // value *= 31;
     
    
- 
    
     
    
    
     	
      // value += ch;
     
    
- 
    
     
    
    
     	
      // }
     
    
- 
    
     
    
    
     	
      // return value;
     
    
- 
    
     
    
    
     	
      // }
     
    
- 
    
     
    
    
     	
      //};
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     	
      template<
      class 
      K, 
      class 
      V, 
      class 
      HashFunc = Hash<K>>
     
    
- 
    
     
    
    
     	
      class HashTable
     
    
- 
    
     
    
    
     
      	{
     
    
- 
    
     
    
    
     	
      public:
     
    
- 
    
     
    
    
     		
      bool 
      Erase(
      const K& key)
     
    
- 
    
     
    
    
     
      		{
     
    
- 
    
     
    
    
     
      			HashData<K, V>* ret = 
      Find(key);
     
    
- 
    
     
    
    
     			
      if (ret == 
      nullptr)
     
    
- 
    
     
    
    
     
      			{
     
    
- 
    
     
    
    
     				
      return 
      false;
     
    
- 
    
     
    
    
     
      			}
     
    
- 
    
     
    
    
     			
      else
     
    
- 
    
     
    
    
     
      			{
     
    
- 
    
     
    
    
     
      				--_n;
     
    
- 
    
     
    
    
     
      				ret->_status = DELETE;
     
    
- 
    
     
    
    
     				
      return 
      true;
     
    
- 
    
     
    
    
     
      			}
     
    
- 
    
     
    
    
     
      		}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     		
      HashData<K, V>* Find(const K& key)
     
    
- 
    
     
    
    
     
      		{
     
    
- 
    
     
    
    
     			
      if (_tables.
      size() == 
      0)
     
    
- 
    
     
    
    
     
      			{
     
    
- 
    
     
    
    
     				
      return 
      nullptr;
     
    
- 
    
     
    
    
     
      			}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      			HashFunc hf;
     
    
- 
    
     
    
    
     			
      size_t start = 
      hf(key) % _tables.
      size();
     
    
- 
    
     
    
    
     			
      size_t i = 
      0;
     
    
- 
    
     
    
    
     			
      size_t index = start;
     
    
- 
    
     
    
    
     			
      //线性探测 or 二次探测
     
    
- 
    
     
    
    
     			
      while (_tables[index]._status != EMPTY)
     
    
- 
    
     
    
    
     
      			{
     
    
- 
    
     
    
    
     				
      if (_tables[index]._kv.first == key && _tables[index]._status == EXIST)
     
    
- 
    
     
    
    
     
      				{
     
    
- 
    
     
    
    
     					
      return &_tables[index];
     
    
- 
    
     
    
    
     
      				}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      				++i;
     
    
- 
    
     
    
    
     				
      //index = start + i*i;
     
    
- 
    
     
    
    
     
      				index = start + i;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      				index %= _tables.
      size();
     
    
- 
    
     
    
    
     
      			}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     			
      return 
      nullptr;
     
    
- 
    
     
    
    
     
      		}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     		
      bool Insert(const pair<K, V>& kv)
     
    
- 
    
     
    
    
     
      		{
     
    
- 
    
     
    
    
     
      			HashData<K, V>* ret = 
      Find(kv.first);
     
    
- 
    
     
    
    
     			
      if (ret)
     
    
- 
    
     
    
    
     
      			{
     
    
- 
    
     
    
    
     				
      return 
      false;
     
    
- 
    
     
    
    
     
      			}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     			
      //负载因子到0.7,就扩容
     
    
- 
    
     
    
    
     			
      //负载因子越小,冲突概率越低,效率越高,空间浪费越多
     
    
- 
    
     
    
    
     			
      //负载因子越大,冲突概率越高,效率越低,空间浪费越少
     
    
- 
    
     
    
    
     			
      if (_tables.
      size() == 
      0 || _n * 
      10 / _tables.
      size() >= 
      7)
     
    
- 
    
     
    
    
     
      			{
     
    
- 
    
     
    
    
     				
      //扩容
     
    
- 
    
     
    
    
     				
      size_t newSize = _tables.
      size() == 
      0 ? 
      10 : _tables.
      size() * 
      2;
     
    
- 
    
     
    
    
     				
      //vector<HashData<K,V>> newTables;
     
    
- 
    
     
    
    
     				
      //newTables.resize(newSize);
     
    
- 
    
     
    
    
     				
      //遍历原表,把原表中的数据,重新按newSize映射到新表
     
    
- 
    
     
    
    
     				
      //for(size_t i = 0;i < _tables.size();++i)
     
    
- 
    
     
    
    
     				
      //{
     
    
- 
    
     
    
    
     					
      //
     
    
- 
    
     
    
    
     				
      //}
     
    
- 
    
     
    
    
     				
      //_tables.swap(newTables);
     
    
- 
    
     
    
    
     
      				HashTable<K, V, HashFunc> newHT;
     
    
- 
    
     
    
    
     
      				newHT._tables.
      resize(newSize);
     
    
- 
    
     
    
    
     				
      for (
      size_t i = 
      0; i < _tables.
      size(); ++i)
     
    
- 
    
     
    
    
     
      				{
     
    
- 
    
     
    
    
     					
      if (_tables[i]._status == EXIST)
     
    
- 
    
     
    
    
     
      					{
     
    
- 
    
     
    
    
     
      						newHT.
      Insert(_tables[i]._kv);
     
    
- 
    
     
    
    
     
      					}
     
    
- 
    
     
    
    
     
      				}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      				_tables.
      swap(newHT._tables);
     
    
- 
    
     
    
    
     
      			}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      			HashFunc hf;
     
    
- 
    
     
    
    
     			
      size_t start = 
      hf(kv.first) % _tables.
      size();
     
    
- 
    
     
    
    
     			
      size_t i = 
      0;
     
    
- 
    
     
    
    
     			
      size_t index = start;
     
    
- 
    
     
    
    
     			
      //线性探测 or 二次探测
     
    
- 
    
     
    
    
     			
      while (_tables[index]._status == EXIST)
     
    
- 
    
     
    
    
     
      			{
     
    
- 
    
     
    
    
     
      				++i;
     
    
- 
    
     
    
    
     				
      //index = start + i * i;
     
    
- 
    
     
    
    
     
      				index = start + i;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      				index %= _tables.
      size();
     
    
- 
    
     
    
    
     
      			}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      			_tables[index]._kv = kv;
     
    
- 
    
     
    
    
     
      			_tables[index]._status = EXIST;
     
    
- 
    
     
    
    
     
      			++_n;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     			
      return 
      true;
     
    
- 
    
     
    
    
     
      		}
     
    
- 
    
     
    
    
     	
      private:
     
    
- 
    
     
    
    
     
      		vector<HashData<K, V>> _tables;
     
    
- 
    
     
    
    
     		
      size_t _n = 
      0;
      //有效数据个数
     
    
- 
    
     
    
    
     
      	};
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     	
      void TestHashTable1()
     
    
- 
    
     
    
    
     
      	{
     
    
- 
    
     
    
    
     		
      //HashTable<int,int,Hash<int>> ht;
     
    
- 
    
     
    
    
     
      		HashTable<
      int, 
      int> ht;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     		
      int a[] = { 
      2,
      12,
      22,
      32,
      42,
      52,
      62 };
     
    
- 
    
     
    
    
     		
      for (
      auto e : a)
     
    
- 
    
     
    
    
     
      		{
     
    
- 
    
     
    
    
     
      			ht.
      Insert(
      make_pair(e, e));
     
    
- 
    
     
    
    
     
      		}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      		ht.
      Insert(
      make_pair(
      72, 
      72));
     
    
- 
    
     
    
    
     
      		ht.
      Insert(
      make_pair(
      72, 
      72));
     
    
- 
    
     
    
    
     
      		ht.
      Insert(
      make_pair(
      -1, 
      -1));
     
    
- 
    
     
    
    
     
      		ht.
      Insert(
      make_pair(
      -999, 
      -999));
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      		Hash<
      int> hs;
     
    
- 
    
     
    
    
     
      		cout << 
      hs(
      9) << endl;
     
    
- 
    
     
    
    
     
      		cout << 
      hs(
      -9) << endl;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      		cout << ht.
      Find(
      12) << endl;
     
    
- 
    
     
    
    
     
      		ht.
      Erase(
      12);
     
    
- 
    
     
    
    
     
      		cout << ht.
      Find(
      12) << endl;
     
    
- 
    
     
    
    
     
      	}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     	
      struct 
      Date
     
    
- 
    
     
    
    
     
      	{
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      	};
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     	
      struct 
      HashDate
     
    
- 
    
     
    
    
     
      	{
     
    
- 
    
     
    
    
     		
      size_t operator()(const Date& d)
     
    
- 
    
     
    
    
     
      		{
     
    
- 
    
     
    
    
     			
      //...
     
    
- 
    
     
    
    
     
      		}
     
    
- 
    
     
    
    
     
      	};
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     	
      void TestHashTable2()
     
    
- 
    
     
    
    
     
      	{
     
    
- 
    
     
    
    
     		
      /*HashStr hs;
     
    
- 
    
     
    
    
     
       cout << hs("sort") << endl;
     
    
- 
    
     
    
    
     
       cout << hs("insert") << endl;
     
    
- 
    
     
    
    
     
       cout << hs("eat") << endl;
     
    
- 
    
     
    
    
     
       cout << hs("ate") << endl;
     
    
- 
    
     
    
    
     
       cout << hs("abcd") << endl;
     
    
- 
    
     
    
    
     
       cout << hs("aadd") << endl;*/
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      		HashTable<string, string> ht;
     
    
- 
    
     
    
    
     
      		ht.
      Insert(
      make_pair(
      "sort", 
      "排序"));
     
    
- 
    
     
    
    
     
      		ht.
      Insert(
      make_pair(
      "string", 
      "字符串"));
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     		
      //当key是一个定义类型时,需要配置一个仿函数,将key转成整形
     
    
- 
    
     
    
    
     
      		HashTable<Date, string, HashDate> htds;
     
    
- 
    
     
    
    
     
      	}
     
    
- 
    
     
    
    
     
      }
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      namespace LinkHash
     
    
- 
    
     
    
    
     
      {
     
    
- 
    
     
    
    
     	
      template<
      class 
      T>
     
    
- 
    
     
    
    
     	
      struct 
      HashNode
     
    
- 
    
     
    
    
     
      	{
     
    
- 
    
     
    
    
     
      		T _data;
     
    
- 
    
     
    
    
     
      		HashNode<T>* _next;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     		
      HashNode(
      const T& data) :_data(data), _next(
      nullptr)
     
    
- 
    
     
    
    
     
      		{}
     
    
- 
    
     
    
    
     
      	};
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     	
      template<
      class 
      K, 
      class 
      T,
      class 
      KeyOfT, 
      class 
      HashFunc>
     
    
- 
    
     
    
    
     	
      class 
      HashTable;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     	
      template<
      class 
      K,
      class 
      T,
      class 
      Ref,
      class 
      Ptr,
      class 
      KeyOfT,
      class 
      HashFunc>
     
    
- 
    
     
    
    
     	
      struct 
      __HTIterator
     
    
- 
    
     
    
    
     
      	{
     
    
- 
    
     
    
    
     		
      typedef HashNode<T> Node;
     
    
- 
    
     
    
    
     		
      typedef __HTIterator<K, T, Ref, Ptr, KeyOfT, HashFunc> Self;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      		Node* _node;
     
    
- 
    
     
    
    
     
      		HashTable<K, T, KeyOfT, HashFunc>* _pht;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      		__HTIterator(Node* node,HashTable<K,T,KeyOfT,HashFunc>* 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;
     
    
- 
    
     
    
    
     
      				HashFunc hf;
     
    
- 
    
     
    
    
     				
      size_t index = 
      hf(
      kot(_node->_data)) % _pht->_tables.
      size();
     
    
- 
    
     
    
    
     
      				++index;
     
    
- 
    
     
    
    
     				
      //找下一个不为空的值
     
    
- 
    
     
    
    
     				
      while (index < _pht->_tables.
      size())
     
    
- 
    
     
    
    
     
      				{
     
    
- 
    
     
    
    
     					
      if (_pht->_tables[index])
     
    
- 
    
     
    
    
     
      					{
     
    
- 
    
     
    
    
     						
      break;
     
    
- 
    
     
    
    
     
      					}
     
    
- 
    
     
    
    
     					
      else
     
    
- 
    
     
    
    
     
      					{
     
    
- 
    
     
    
    
     
      						++index;
     
    
- 
    
     
    
    
     
      					}
     
    
- 
    
     
    
    
     
      				}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     				
      //表走完了,都没有找到下一个桶
     
    
- 
    
     
    
    
     				
      if (index == _pht->_tables.
      size())
     
    
- 
    
     
    
    
     
      				{
     
    
- 
    
     
    
    
     
      					_node = 
      nullptr;
     
    
- 
    
     
    
    
     
      				}
     
    
- 
    
     
    
    
     				
      else
     
    
- 
    
     
    
    
     
      				{
     
    
- 
    
     
    
    
     
      					_node = _pht->_tables[index];
     
    
- 
    
     
    
    
     
      				}
     
    
- 
    
     
    
    
     
      			}
     
    
- 
    
     
    
    
     			
      return *
      this;
     
    
- 
    
     
    
    
     
      		}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     		
      bool 
      operator!=(
      const Self& s) 
      const
     
    
- 
    
     
    
    
     
      		{
     
    
- 
    
     
    
    
     			
      return _node != s._node;
     
    
- 
    
     
    
    
     
      		}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     		
      bool 
      operator==(
      const Self& s) 
      const
     
    
- 
    
     
    
    
     
      		{
     
    
- 
    
     
    
    
     			
      return _node = s._node;
     
    
- 
    
     
    
    
     
      		}
     
    
- 
    
     
    
    
     
      	};
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     	
      template<
      class 
      K,
      class 
      T,
      class 
      KeyOfT,
      class 
      HashFunc>
     
    
- 
    
     
    
    
     	
      class 
      HashTable
     
    
- 
    
     
    
    
     
      	{
     
    
- 
    
     
    
    
     		
      typedef HashNode<T> Node;
     
    
- 
    
     
    
    
     		
     
    
- 
    
     
    
    
     		
      template<
      class 
      K,
      class 
      T,
      class 
      Ref,
      class 
      Ptr,
      class 
      KeyOfT,
      class 
      HashFunc>
     
    
- 
    
     
    
    
     		
      friend 
      struct 
      __HTIterator;
     
    
- 
    
     
    
    
     		
      typedef HashTable<K, T, KeyOfT, HashFunc> self;
     
    
- 
    
     
    
    
     	
      public:
     
    
- 
    
     
    
    
     		
      typedef __HTIterator<K, T, T&, T*, KeyOfT, HashFunc> iterator;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     		
      HashTable()
     
    
- 
    
     
    
    
     
      		{}
     
    
- 
    
     
    
    
     		
      //显示指定编译器去生成默认构造函数
     
    
- 
    
     
    
    
     		
      //HashTable() = default;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     		
      HashTable(
      const self& ht)
     
    
- 
    
     
    
    
     
      		{
     
    
- 
    
     
    
    
     
      			_tables.
      resize(ht._tables.
      size());
     
    
- 
    
     
    
    
     			
      for (
      size_t i = 
      0; i < ht._tables.
      size(); ++i)
     
    
- 
    
     
    
    
     
      			{
     
    
- 
    
     
    
    
     
      				Node* cur = ht._tables[i];
     
    
- 
    
     
    
    
     				
      while (cur)
     
    
- 
    
     
    
    
     
      				{
     
    
- 
    
     
    
    
     
      					Node* copy = 
      new 
      Node(cur->_data);
     
    
- 
    
     
    
    
     
      					copy->_next = _tables[i];
     
    
- 
    
     
    
    
     
      					_tables[i] = copy;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      					cur = cur->_next;
     
    
- 
    
     
    
    
     
      				}
     
    
- 
    
     
    
    
     
      			}
     
    
- 
    
     
    
    
     
      		}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     		
      //ht1 = ht2
     
    
- 
    
     
    
    
     
      		self& 
      operator=(self copy)
     
    
- 
    
     
    
    
     
      		{
     
    
- 
    
     
    
    
     			
      swap(_n, copy._n);
     
    
- 
    
     
    
    
     
      			_tables.
      swap(copy._tables);
     
    
- 
    
     
    
    
     			
      return *
      this;
     
    
- 
    
     
    
    
     
      		}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      		~
      HashTable()
     
    
- 
    
     
    
    
     
      		{
     
    
- 
    
     
    
    
     			
      for (
      size_t i = 
      0; i < _tables.
      size(); ++i)
     
    
- 
    
     
    
    
     
      			{
     
    
- 
    
     
    
    
     
      				Node* cur = _tables[i];
     
    
- 
    
     
    
    
     				
      while (cur)
     
    
- 
    
     
    
    
     
      				{
     
    
- 
    
     
    
    
     
      					Node* next = cur->_next;
     
    
- 
    
     
    
    
     					
      delete cur;
     
    
- 
    
     
    
    
     
      					cur = next;
     
    
- 
    
     
    
    
     
      				}
     
    
- 
    
     
    
    
     
      				_tables[i] = 
      nullptr;
     
    
- 
    
     
    
    
     
      			}
     
    
- 
    
     
    
    
     
      		}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     		
      iterator begin()
     
    
- 
    
     
    
    
     
      		{
     
    
- 
    
     
    
    
     			
      for (
      size_t i = 
      0; i < _tables.
      size(); ++i)
     
    
- 
    
     
    
    
     
      			{
     
    
- 
    
     
    
    
     				
      if (_tables[i])
     
    
- 
    
     
    
    
     
      				{
     
    
- 
    
     
    
    
     					
      return 
      iterator(_tables[i], 
      this);
     
    
- 
    
     
    
    
     
      				}
     
    
- 
    
     
    
    
     
      			}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     			
      return 
      end();
     
    
- 
    
     
    
    
     
      		}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     		
      iterator end()
     
    
- 
    
     
    
    
     
      		{
     
    
- 
    
     
    
    
     			
      return 
      iterator(
      nullptr, 
      this);
     
    
- 
    
     
    
    
     
      		}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     		
      bool Erase(const K& key)
     
    
- 
    
     
    
    
     
      		{
     
    
- 
    
     
    
    
     			
      if (_tables.
      empty())
     
    
- 
    
     
    
    
     
      			{
     
    
- 
    
     
    
    
     				
      return 
      false;
     
    
- 
    
     
    
    
     
      			}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      			HashFunc hf;
     
    
- 
    
     
    
    
     			
      size_t index = 
      hf(key) % _tables.
      size();
     
    
- 
    
     
    
    
     
      			Node* prev = 
      nullptr;
     
    
- 
    
     
    
    
     
      			Node* cur = _tables[index];
     
    
- 
    
     
    
    
     
      			KeyOfT kot;
     
    
- 
    
     
    
    
     			
      while (cur)
     
    
- 
    
     
    
    
     
      			{
     
    
- 
    
     
    
    
     				
      if (
      kot(cur->_data) == key)
     
    
- 
    
     
    
    
     
      				{
     
    
- 
    
     
    
    
     					
      if (prev == 
      nullptr) 
      //头删
     
    
- 
    
     
    
    
     
      					{
     
    
- 
    
     
    
    
     
      						_tables[index] = cur->_next;
     
    
- 
    
     
    
    
     
      					}
     
    
- 
    
     
    
    
     					
      else 
      //中间删除
     
    
- 
    
     
    
    
     
      					{
     
    
- 
    
     
    
    
     
      						prev->_next = cur->_next;
     
    
- 
    
     
    
    
     
      					}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      					--_n;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     					
      delete cur;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     					
      return 
      true;
     
    
- 
    
     
    
    
     
      				}
     
    
- 
    
     
    
    
     				
      else
     
    
- 
    
     
    
    
     
      				{
     
    
- 
    
     
    
    
     
      					prev = cur;
     
    
- 
    
     
    
    
     
      					cur = cur->_next;
     
    
- 
    
     
    
    
     
      				}
     
    
- 
    
     
    
    
     
      			}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     			
      return 
      false;
     
    
- 
    
     
    
    
     
      		}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     		
      iterator Find(const K& key)
     
    
- 
    
     
    
    
     
      		{
     
    
- 
    
     
    
    
     			
      if (_tables.
      empty())
     
    
- 
    
     
    
    
     
      			{
     
    
- 
    
     
    
    
     				
      return 
      end();
     
    
- 
    
     
    
    
     
      			}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      			HashFunc hf;
     
    
- 
    
     
    
    
     			
      size_t index = 
      hf(key) % _tables.
      size();
     
    
- 
    
     
    
    
     
      			Node* cur = _tables[index];
     
    
- 
    
     
    
    
     
      			KeyOfT kot;
     
    
- 
    
     
    
    
     			
      while (cur)
     
    
- 
    
     
    
    
     
      			{
     
    
- 
    
     
    
    
     				
      if (
      kot(cur->_data) == key)
     
    
- 
    
     
    
    
     
      				{
     
    
- 
    
     
    
    
     					
      return 
      iterator(cur,
      this);
     
    
- 
    
     
    
    
     
      				}
     
    
- 
    
     
    
    
     				
      else
     
    
- 
    
     
    
    
     
      				{
     
    
- 
    
     
    
    
     
      					cur = cur->_next;
     
    
- 
    
     
    
    
     
      				}
     
    
- 
    
     
    
    
     
      			}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     			
      return 
      end();
     
    
- 
    
     
    
    
     
      		}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     		
      size_t GetNextPrime(size_t num)
     
    
- 
    
     
    
    
     
      		{
     
    
- 
    
     
    
    
     			
      static 
      const 
      unsigned 
      long __stl_prime_list[
      28] =
     
    
- 
    
     
    
    
     
      			{
     
    
- 
    
     
    
    
     				
      53,
      97,
      193,
      389,
      769,
     
    
- 
    
     
    
    
     				
      1543,
      3079,
      6151,
      12289,
      24593,
     
    
- 
    
     
    
    
     				
      49157,
      98317,
      196613,
      393241,
      786433,
     
    
- 
    
     
    
    
     				
      1572869,
      3145739,
      6291469,
      12582917,
      25165843,
     
    
- 
    
     
    
    
     				
      50331653,
      100663319,
      201326611,
      402653189,
      805306457,
     
    
- 
    
     
    
    
     				
      1610612741,
      3221225473,
      4294967291
     
    
- 
    
     
    
    
     
      			};
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     			
      for(
      size_t i = 
      0;i < 
      28;++i)
     
    
- 
    
     
    
    
     
      			{
     
    
- 
    
     
    
    
     				
      if (__stl_prime_list[i] > num)
     
    
- 
    
     
    
    
     
      				{
     
    
- 
    
     
    
    
     					
      return __stl_prime_list[i];
     
    
- 
    
     
    
    
     
      				}
     
    
- 
    
     
    
    
     
      			}
     
    
- 
    
     
    
    
     			
      return __stl_prime_list[
      27];
     
    
- 
    
     
    
    
     
      		}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     		
      pair<iterator,bool> Insert(const T& data)
     
    
- 
    
     
    
    
     
      		{
     
    
- 
    
     
    
    
     
      			KeyOfT kot;
     
    
- 
    
     
    
    
     
      			iterator ret = 
      Find(
      kot(data));
     
    
- 
    
     
    
    
     			
      if (ret != 
      end())
     
    
- 
    
     
    
    
     				
      return 
      make_pair(ret,
      false);
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      			HashFunc hf;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     			
      //负载因子 == 1时扩容
     
    
- 
    
     
    
    
     			
      if (_n == _tables.
      size())
     
    
- 
    
     
    
    
     
      			{
     
    
- 
    
     
    
    
     				
      //size_t newSize = _tables.size() == 0 ? 10 : _tables.size() * 2;
     
    
- 
    
     
    
    
     				
      //...
     
    
- 
    
     
    
    
     				
      size_t newSize = 
      GetNextPrime(_tables.
      size());
     
    
- 
    
     
    
    
     				
      /*if (newSize == _tables.size())
     
    
- 
    
     
    
    
     
       {
     
    
- 
    
     
    
    
     
       break;
     
    
- 
    
     
    
    
     
       }*/
     
    
- 
    
     
    
    
     
      				vector<Node*> newTables;
     
    
- 
    
     
    
    
     
      				newTables.
      resize(newSize);
     
    
- 
    
     
    
    
     				
      for (
      size_t i = 
      0; i < _tables.
      size(); ++i)
     
    
- 
    
     
    
    
     
      				{
     
    
- 
    
     
    
    
     
      					Node* cur = _tables[i];
     
    
- 
    
     
    
    
     					
      while (cur)
     
    
- 
    
     
    
    
     
      					{
     
    
- 
    
     
    
    
     
      						Node* next = cur->_next;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     						
      size_t index = 
      hf(
      kot(cur->_data)) % newTables.
      size();
     
    
- 
    
     
    
    
     						
      //头插
     
    
- 
    
     
    
    
     
      						cur->_next = newTables[index];
     
    
- 
    
     
    
    
     
      						newTables[index] = cur;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      						cur = next;
     
    
- 
    
     
    
    
     
      					}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      					_tables[i] = 
      nullptr;
     
    
- 
    
     
    
    
     
      				}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      				_tables.
      swap(newTables);
     
    
- 
    
     
    
    
     
      			}
     
    
- 
    
     
    
    
     			
      size_t index = 
      hf(
      kot(data)) % _tables.
      size();
     
    
- 
    
     
    
    
     
      			Node* newnode = 
      new 
      Node(data);
     
    
- 
    
     
    
    
     			
      //头插
     
    
- 
    
     
    
    
     
      			newnode->_next = _tables[index];
     
    
- 
    
     
    
    
     
      			_tables[index] = newnode;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      			++_n;
     
    
- 
    
     
    
    
     			
      return 
      make_pair(
      iterator(newnode,
      this),
      false);
     
    
- 
    
     
    
    
     
      		}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     	
      private:
     
    
- 
    
     
    
    
     		
      /*struct Data
     
    
- 
    
     
    
    
     
       {
     
    
- 
    
     
    
    
     
       forward_list<T> _list;
     
    
- 
    
     
    
    
     
       set<T> _rbtree;
     
    
- 
    
     
    
    
     
       size_t len;
     
    
- 
    
     
    
    
     
       };
     
    
- 
    
     
    
    
     
       vector<Data> _table;*/
     
    
- 
    
     
    
    
     
      		vector<Node*> _tables;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     		
      size_t _n = 
      0;
      //有效数据的个数
     
    
- 
    
     
    
    
     
      	};
     
    
- 
    
     
    
    
     
      }
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      //unordered-map
     
    
- 
    
     
    
    
     
      #pragma once
     
    
- 
    
     
    
    
     
      #include"HashTable.h"
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      namespace bit
     
    
- 
    
     
    
    
     
      {
     
    
- 
    
     
    
    
     	
      template<
      class 
      K,
      class 
      V,
      class 
      hash = Hash<K>>
     
    
- 
    
     
    
    
     	
      class unordered_map
     
    
- 
    
     
    
    
     
      	{
     
    
- 
    
     
    
    
     		
      struct MapKeyOfT
     
    
- 
    
     
    
    
     
      		{
     
    
- 
    
     
    
    
     			
      const K& 
      operator()(
      const pair<K, V>& kv)
     
    
- 
    
     
    
    
     
      			{
     
    
- 
    
     
    
    
     				
      return kv.first;
     
    
- 
    
     
    
    
     
      			}
     
    
- 
    
     
    
    
     
      		};
     
    
- 
    
     
    
    
     	
      public:
     
    
- 
    
     
    
    
     		
      typedef 
      typename LinkHash::HashTable<K, pair<K, V>, MapKeyOfT, hash>::iterator iterator;
     
    
- 
    
     
    
    
     		
      iterator begin()
     
    
- 
    
     
    
    
     
      		{
     
    
- 
    
     
    
    
     			
      return _ht.
      begin();
     
    
- 
    
     
    
    
     
      		}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     		
      iterator end()
     
    
- 
    
     
    
    
     
      		{
     
    
- 
    
     
    
    
     			
      return _ht.
      end();
     
    
- 
    
     
    
    
     
      		}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      		V& 
      operator[](
      const K& key)
     
    
- 
    
     
    
    
     
      		{
     
    
- 
    
     
    
    
     			
      auto ret = _ht.
      Insert(
      make_pair(key, 
      V()));
     
    
- 
    
     
    
    
     			
      return ret.first->second;
     
    
- 
    
     
    
    
     
      		}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     		
      pair<iterator,bool> insert(const pair<K, V>& kv)
     
    
- 
    
     
    
    
     
      		{
     
    
- 
    
     
    
    
     			
      return _ht.
      Insert(kv);
     
    
- 
    
     
    
    
     
      		}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     	
      private:
     
    
- 
    
     
    
    
     
      		LinkHash::HashTable<K, pair<K,V>, MapKeyOfT, hash > _ht;
     
    
- 
    
     
    
    
     
      	};
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     	
      void test_unordered_map()
     
    
- 
    
     
    
    
     
      	{
     
    
- 
    
     
    
    
     
      		unordered_map<string, string> dict;
     
    
- 
    
     
    
    
     
      		dict.
      insert(
      make_pair(
      "sort", 
      "排序"));
     
    
- 
    
     
    
    
     
      		dict.
      insert(
      make_pair(
      "string", 
      "字符串"));
     
    
- 
    
     
    
    
     
      		dict.
      insert(
      make_pair(
      "map", 
      "地图、映射"));
     
    
- 
    
     
    
    
     		
      /*cout << dict["sort"] << endl;
     
    
- 
    
     
    
    
     
       cout << dict["string"] << endl;
     
    
- 
    
     
    
    
     
       cout << dict["map"] << endl;*/
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     		
      //dict["right"] = "右边";
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      		unordered_map<string, string>::iterator it = dict.
      begin();
     
    
- 
    
     
    
    
     		
      while (it != dict.
      end())
     
    
- 
    
     
    
    
     
      		{
     
    
- 
    
     
    
    
     
      			cout << it->first << 
      ":" << it->second << endl;
     
    
- 
    
     
    
    
     
      			++it;
     
    
- 
    
     
    
    
     
      		}
     
    
- 
    
     
    
    
     
      		cout << endl;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     		
      unordered_map<string, string> copy(dict);
     
    
- 
    
     
    
    
     		
      for (
      auto& kv : copy)
     
    
- 
    
     
    
    
     
      		{
     
    
- 
    
     
    
    
     
      			cout << kv.first << 
      ":" << kv.second << endl;
     
    
- 
    
     
    
    
     
      		}
     
    
- 
    
     
    
    
     
      		cout << endl;
     
    
- 
    
     
    
    
     
      	}
     
    
- 
    
     
    
    
     
      }
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      //unordered-set
     
    
- 
    
     
    
    
     
      #pragma once
     
    
- 
    
     
    
    
     
      namespace bit
     
    
- 
    
     
    
    
     
      {
     
    
- 
    
     
    
    
     	
      template<
      class 
      K,
      class 
      hash = Hash<K>>
     
    
- 
    
     
    
    
     	
      class unordered_set
     
    
- 
    
     
    
    
     
      	{
     
    
- 
    
     
    
    
     		
      struct SetKeyOfT
     
    
- 
    
     
    
    
     
      		{
     
    
- 
    
     
    
    
     			
      const K& 
      operator()(
      const K& key)
     
    
- 
    
     
    
    
     
      			{
     
    
- 
    
     
    
    
     				
      return key;
     
    
- 
    
     
    
    
     
      			}
     
    
- 
    
     
    
    
     
      		};
     
    
- 
    
     
    
    
     	
      public:
     
    
- 
    
     
    
    
     		
      typedef 
      typename LinkHash::HashTable<K, K, SetKeyOfT, hash>::iterator iterator;
     
    
- 
    
     
    
    
     		
      iterator begin()
     
    
- 
    
     
    
    
     
      		{
     
    
- 
    
     
    
    
     			
      return _ht.
      begin();
     
    
- 
    
     
    
    
     
      		}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     		
      iterator end()
     
    
- 
    
     
    
    
     
      		{
     
    
- 
    
     
    
    
     			
      return _ht.
      end();
     
    
- 
    
     
    
    
     
      		}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     		
      pair<iterator,bool> insert(const K& key)
     
    
- 
    
     
    
    
     
      		{
     
    
- 
    
     
    
    
     			
      return _ht.
      Insert(key);
     
    
- 
    
     
    
    
     
      		}
     
    
- 
    
     
    
    
     	
      private:
     
    
- 
    
     
    
    
     
      		LinkHash::HashTable<K, K, SetKeyOfT, hash> _ht;
     
    
- 
    
     
    
    
     
      	};
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     	
      void test_unordered_set()
     
    
- 
    
     
    
    
     
      	{
     
    
- 
    
     
    
    
     
      		unordered_set<
      int> us;
     
    
- 
    
     
    
    
     
      		us.
      insert(
      4);
     
    
- 
    
     
    
    
     
      		us.
      insert(
      14);
     
    
- 
    
     
    
    
     
      		us.
      insert(
      34);
     
    
- 
    
     
    
    
     
      		us.
      insert(
      7);
     
    
- 
    
     
    
    
     
      		us.
      insert(
      24);
     
    
- 
    
     
    
    
     
      		us.
      insert(
      17);
     
    
- 
    
     
    
    
     
      		unordered_set<
      int>::iterator it = us.
      begin();
     
    
- 
    
     
    
    
     		
      while (it != us.
      end())
     
    
- 
    
     
    
    
     
      		{
     
    
- 
    
     
    
    
     
      			cout << *it << 
      " ";
     
    
- 
    
     
    
    
     
      			++it;
     
    
- 
    
     
    
    
     
      		}
     
    
- 
    
     
    
    
     
      		cout << endl;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     		
      unordered_set<int> uss(us);
     
    
- 
    
     
    
    
     
      		unordered_set<
      int>::iterator It = uss.
      begin();
     
    
- 
    
     
    
    
     		
      while (It != uss.
      end())
     
    
- 
    
     
    
    
     
      		{
     
    
- 
    
     
    
    
     
      			cout << *It << 
      " ";
     
    
- 
    
     
    
    
     
      			++It;
     
    
- 
    
     
    
    
     
      		}
     
    
- 
    
     
    
    
     
      		cout << endl;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     		
      /*unordered_set<string> uss;
     
    
- 
    
     
    
    
     
       uss.insert("sort");
     
    
- 
    
     
    
    
     
       uss.insert("hash");*/
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     		
      /*unordered_set<int> us;
     
    
- 
    
     
    
    
     
       for (size_t i = 0; i < 100; ++i)
     
    
- 
    
     
    
    
     
       {
     
    
- 
    
     
    
    
     
       us.insert(i);
     
    
- 
    
     
    
    
     
       }*/
     
    
- 
    
     
    
    
     
      	}
     
    
- 
    
     
    
    
     
      }
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      //bitSet
     
    
- 
    
     
    
    
     
      #pragma once
     
    
- 
    
     
    
    
     
      #include<vector>
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      namespace bit
     
    
- 
    
     
    
    
     
      {
     
    
- 
    
     
    
    
     	
      template<
      size_t N>
     
    
- 
    
     
    
    
     	
      class 
      bitset
     
    
- 
    
     
    
    
     
      	{
     
    
- 
    
     
    
    
     	
      public:
     
    
- 
    
     
    
    
     		
      bitset()
     
    
- 
    
     
    
    
     
      		{
     
    
- 
    
     
    
    
     
      			_bits.
      resize(N / 
      8 + 
      1, 
      0);
     
    
- 
    
     
    
    
     
      		}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     		
      void set(size_t x)
     
    
- 
    
     
    
    
     
      		{
     
    
- 
    
     
    
    
     			
      size_t i = x / 
      8;
     
    
- 
    
     
    
    
     			
      size_t j = x % 
      8;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      			_bits[i] |= (
      1 << j);
     
    
- 
    
     
    
    
     
      		}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     		
      void reset(size_t x)
     
    
- 
    
     
    
    
     
      		{
     
    
- 
    
     
    
    
     			
      size_t i = x / 
      8;
     
    
- 
    
     
    
    
     			
      size_t j = x % 
      8;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      			_bits[i] &= (~(
      1 << j));
     
    
- 
    
     
    
    
     
      		}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     		
      bool test(size_t x)
     
    
- 
    
     
    
    
     
      		{
     
    
- 
    
     
    
    
     			
      size_t i = x / 
      8;
     
    
- 
    
     
    
    
     			
      size_t j = x % 
      8;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     			
      return _bits[i] & (
      1 << j);
     
    
- 
    
     
    
    
     
      		}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     	
      private:
     
    
- 
    
     
    
    
     
      		std::vector<
      char> _bits;
     
    
- 
    
     
    
    
     		
      //std::vector<int> _bits;
     
    
- 
    
     
    
    
     
      	};
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     	
      void test_bitset()
     
    
- 
    
     
    
    
     
      	{
     
    
- 
    
     
    
    
     
      		bitset<100> bs;
     
    
- 
    
     
    
    
     
      		bs.
      set(
      5);
     
    
- 
    
     
    
    
     
      		bs.
      set(
      4);
     
    
- 
    
     
    
    
     
      		bs.
      set(
      10);
     
    
- 
    
     
    
    
     
      		bs.
      set(
      20);
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      		cout << bs.
      test(
      5) << endl;
     
    
- 
    
     
    
    
     
      		cout << bs.
      test(
      4) << endl;
     
    
- 
    
     
    
    
     
      		cout << bs.
      test(
      10) << endl;
     
    
- 
    
     
    
    
     
      		cout << bs.
      test(
      20) << endl;
     
    
- 
    
     
    
    
     
      		cout << bs.
      test(
      21) << endl;
     
    
- 
    
     
    
    
     
      		cout << bs.
      test(
      6) << endl << endl;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      		bs.
      reset(
      20);
     
    
- 
    
     
    
    
     
      		bs.
      reset(
      10);
     
    
- 
    
     
    
    
     
      		bs.
      reset(
      5);
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      		cout << bs.
      test(
      5) << endl;
     
    
- 
    
     
    
    
     
      		cout << bs.
      test(
      4) << endl;
     
    
- 
    
     
    
    
     
      		cout << bs.
      test(
      10) << endl;
     
    
- 
    
     
    
    
     
      		cout << bs.
      test(
      20) << endl;
     
    
- 
    
     
    
    
     
      		cout << bs.
      test(
      21) << endl;
     
    
- 
    
     
    
    
     
      		cout << bs.
      test(
      6) << endl;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     		
      //bitset<0xffffffff> bs;
     
    
- 
    
     
    
    
     		
      //bitset<-1> bs;
     
    
- 
    
     
    
    
     
      	}
     
    
- 
    
     
    
    
     
      }
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      template<
      size_t N>
     
    
- 
    
     
    
    
     
      class 
      TwoBitSet
     
    
- 
    
     
    
    
     
      {
     
    
- 
    
     
    
    
     
      public:
     
    
- 
    
     
    
    
     	
      void Set(size_t x)
     
    
- 
    
     
    
    
     
      	{
     
    
- 
    
     
    
    
     		
      if (!_bs1.
      test(x) && !_bs2.
      test(x)) 
      //00 -> 01
     
    
- 
    
     
    
    
     
      		{
     
    
- 
    
     
    
    
     
      			_bs2.
      set(x);
     
    
- 
    
     
    
    
     
      		}
     
    
- 
    
     
    
    
     		
      else 
      if (!_bs1.
      test(x) && _bs2.
      test(x)) 
      //01 -> 10
     
    
- 
    
     
    
    
     
      		{
     
    
- 
    
     
    
    
     
      			_bs1.
      set(x);
     
    
- 
    
     
    
    
     
      			_bs2.
      reset(x);
     
    
- 
    
     
    
    
     
      		}
     
    
- 
    
     
    
    
     		
      //10 表示已经出现2次或以上,不用处理
     
    
- 
    
     
    
    
     
      	}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     	
      void PrintOnceNum()
     
    
- 
    
     
    
    
     
      	{
     
    
- 
    
     
    
    
     		
      for (
      size_t i = 
      0; i < N; ++i)
     
    
- 
    
     
    
    
     
      		{
     
    
- 
    
     
    
    
     			
      if (!_bs1.
      test(i) && _bs2.
      test(i)) 
      // 01
     
    
- 
    
     
    
    
     
      			{
     
    
- 
    
     
    
    
     
      				cout << i << endl;
     
    
- 
    
     
    
    
     
      			}
     
    
- 
    
     
    
    
     
      		}
     
    
- 
    
     
    
    
     
      	}
     
    
- 
    
     
    
    
     
      private:
     
    
- 
    
     
    
    
     
      	bit::bitset<N> _bs1;
     
    
- 
    
     
    
    
     
      	bit::bitset<N> _bs2;
     
    
- 
    
     
    
    
     
      };
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      void TestTwoBitSet()
     
    
- 
    
     
    
    
     
      {
     
    
- 
    
     
    
    
     	
      int a[] = { 
      99,
      0,
      4,
      50,
      33,
      44,
      2,
      5,
      99,
      0,
      50,
      99,
      50,
      2 };
     
    
- 
    
     
    
    
     
      	TwoBitSet<
      100> bs;
     
    
- 
    
     
    
    
     	
      for (
      auto e : a)
     
    
- 
    
     
    
    
     
      	{
     
    
- 
    
     
    
    
     
      		bs.
      Set(e);
     
    
- 
    
     
    
    
     
      	}
     
    
- 
    
     
    
    
     
      	bs.
      PrintOnceNum();
     
    
- 
    
     
    
    
     
      }
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      void TestFindIntersection()
     
    
- 
    
     
    
    
     
      {
     
    
- 
    
     
    
    
     	
      int a1[] = { 
      5,
      30,
      1,
      99,
      10 };
     
    
- 
    
     
    
    
     	
      int a2[] = { 
      8,
      10,
      11,
      9,
      30,
      10,
      30 };
     
    
- 
    
     
    
    
     
      }
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      //BloomFilter
     
    
- 
    
     
    
    
     
      #pragma once
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      #include<bitset>
     
    
- 
    
     
    
    
     
      #include<string>
     
    
- 
    
     
    
    
     
      #include<time.h>
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      struct 
      BKDRHash
     
    
- 
    
     
    
    
     
      {
     
    
- 
    
     
    
    
     	
      size_t operator()(const string& s)
     
    
- 
    
     
    
    
     
      	{
     
    
- 
    
     
    
    
     		
      //BKDR
     
    
- 
    
     
    
    
     		
      size_t value = 
      0;
     
    
- 
    
     
    
    
     		
      for (
      auto ch : s)
     
    
- 
    
     
    
    
     
      		{
     
    
- 
    
     
    
    
     
      			value *= 
      3;
     
    
- 
    
     
    
    
     
      			value += ch;
     
    
- 
    
     
    
    
     
      		}
     
    
- 
    
     
    
    
     		
      return value;
     
    
- 
    
     
    
    
     
      	}
     
    
- 
    
     
    
    
     
      };
     
    
- 
    
     
    
    
     
      struct 
      APHash
     
    
- 
    
     
    
    
     
      {
     
    
- 
    
     
    
    
         
      size_t operator()(const string& s)
     
    
- 
    
     
    
    
     
          {
     
    
- 
    
     
    
    
             
      size_t hash = 
      0;
     
    
- 
    
     
    
    
             
      for (
      long i = 
      0; i < s.
      size(); i++)
     
    
- 
    
     
    
    
     
              {
     
    
- 
    
     
    
    
                 
      if ((i & 
      1) == 
      0)
     
    
- 
    
     
    
    
     
                  {
     
    
- 
    
     
    
    
     
                      hash ^= ((hash << 
      7) ^ s[i] ^ (hash >> 
      3));
     
    
- 
    
     
    
    
     
                  }
     
    
- 
    
     
    
    
                 
      else
     
    
- 
    
     
    
    
     
                  {
     
    
- 
    
     
    
    
     
                      hash ^= (~((hash << 
      11) ^ s[i] ^ (hash >> 
      5)));
     
    
- 
    
     
    
    
     
                  }
     
    
- 
    
     
    
    
     
              }
     
    
- 
    
     
    
    
             
      return hash;
     
    
- 
    
     
    
    
     
          }
     
    
- 
    
     
    
    
     
      };
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      struct 
      DJBHash
     
    
- 
    
     
    
    
     
      {
     
    
- 
    
     
    
    
         
      size_t operator()(const string& s)
     
    
- 
    
     
    
    
     
          {
     
    
- 
    
     
    
    
             
      size_t hash = 
      5381;
     
    
- 
    
     
    
    
             
      for(
      auto ch : s)
     
    
- 
    
     
    
    
     
              {
     
    
- 
    
     
    
    
     
                  hash += (hash << 
      5) + ch;
     
    
- 
    
     
    
    
     
              }
     
    
- 
    
     
    
    
             
      return hash;
     
    
- 
    
     
    
    
     
          }
     
    
- 
    
     
    
    
     
      };
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      template<
      size_t N,
     
    
- 
    
     
    
    
     
      size_t X = 
      8,
     
    
- 
    
     
    
    
     
      class K = string,
     
    
- 
    
     
    
    
     
      class HashFunc1 = BKDRHash,
     
    
- 
    
     
    
    
     
      class HashFunc2 = APHash,
     
    
- 
    
     
    
    
     
      class HashFunc3 = DJBHash>
     
    
- 
    
     
    
    
     
      class BloomFilter
     
    
- 
    
     
    
    
     
      {
     
    
- 
    
     
    
    
     
      public:
     
    
- 
    
     
    
    
         
      void 
      Set(
      const K& key)
     
    
- 
    
     
    
    
     
          {
     
    
- 
    
     
    
    
             
      size_t len = X * N;
     
    
- 
    
     
    
    
             
      size_t index1 = 
      HashFunc1()(key) % len;
     
    
- 
    
     
    
    
             
      size_t index2 = 
      HashFunc2()(key) % len;
     
    
- 
    
     
    
    
             
      size_t index3 = 
      HashFunc3()(key) % len;
     
    
- 
    
     
    
    
     
              cout << index1 << endl;
     
    
- 
    
     
    
    
     
              cout << index2 << endl;
     
    
- 
    
     
    
    
     
              cout << index3 << endl << endl;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
              _bs.
      set(index1);
     
    
- 
    
     
    
    
     
              _bs.
      set(index2);
     
    
- 
    
     
    
    
     
              _bs.
      set(index3);
     
    
- 
    
     
    
    
     
          }
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
         
      bool Test(const K& key)
     
    
- 
    
     
    
    
     
          {
     
    
- 
    
     
    
    
             
      size_t len = X * N;
     
    
- 
    
     
    
    
             
      size_t index1 = 
      HashFunc1()(key) % len;
     
    
- 
    
     
    
    
             
      if (_bs.
      test(index1) == 
      false)
     
    
- 
    
     
    
    
                 
      return 
      false;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
             
      size_t index2 = 
      HashFunc2()(key) % len;
     
    
- 
    
     
    
    
             
      if (_bs.
      test(index2) == 
      false)
     
    
- 
    
     
    
    
                 
      return 
      false;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
             
      size_t index3 = 
      HashFunc3()(key) % len;
     
    
- 
    
     
    
    
             
      if (_bs.
      test(index3) == 
      false)
     
    
- 
    
     
    
    
                 
      return 
      false;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
             
      return 
      true;  
      //存在误判的
     
    
- 
    
     
    
    
     
          }
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
         
      //不支持删除,删除可能会影响其它值。
     
    
- 
    
     
    
    
         
      void Reset(const K& key);
     
    
- 
    
     
    
    
     
      private:
     
    
- 
    
     
    
    
     
          bitset<X* N> _bs;
     
    
- 
    
     
    
    
     
      };
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      void TestBloomFilter1()
     
    
- 
    
     
    
    
     
      {
     
    
- 
    
     
    
    
     
          BloomFilter<
      100> bm;
     
    
- 
    
     
    
    
     
          bm.
      Set(
      "sort");
     
    
- 
    
     
    
    
     
          bm.
      Set(
      "left");
     
    
- 
    
     
    
    
     
          bm.
      Set(
      "right");
     
    
- 
    
     
    
    
     
          bm.
      Set(
      "eat");
     
    
- 
    
     
    
    
     
          bm.
      Set(
      "ate");
     
    
- 
    
     
    
    
     
          bm.
      Set(
      "https://www.cnblogs.com/-clq/archive/2012/05/31/2528153.html");
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      }
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      void TestBloomFilter2()
     
    
- 
    
     
    
    
     
      {
     
    
- 
    
     
    
    
     
          BloomFilter<
      100> bf;
     
    
- 
    
     
    
    
     
          bf.
      Set(
      "张三");
     
    
- 
    
     
    
    
     
          bf.
      Set(
      "李四");
     
    
- 
    
     
    
    
     
          bf.
      Set(
      "牛魔王");
     
    
- 
    
     
    
    
     
          bf.
      Set(
      "红孩儿");
     
    
- 
    
     
    
    
     
          bf.
      Set(
      "eat");
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          cout << bf.
      Test(
      "张三") << endl;
     
    
- 
    
     
    
    
     
          cout << bf.
      Test(
      "李四") << endl;
     
    
- 
    
     
    
    
     
          cout << bf.
      Test(
      "牛魔王") << endl;
     
    
- 
    
     
    
    
     
          cout << bf.
      Test(
      "红孩儿") << endl;
     
    
- 
    
     
    
    
     
          cout << bf.
      Test(
      "孙悟空") << endl;
     
    
- 
    
     
    
    
     
          cout << bf.
      Test(
      "二郎神") << endl;
     
    
- 
    
     
    
    
     
          cout << bf.
      Test(
      "猪八戒") << endl;
     
    
- 
    
     
    
    
     
          cout << bf.
      Test(
      "ate") << endl;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
         
      //BloomFilter<100> bf;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
         
      srand(
      time(
      0));
     
    
- 
    
     
    
    
         
      size_t N = 
      100;
     
    
- 
    
     
    
    
     
          std::vector<std::string> v1;
     
    
- 
    
     
    
    
         
      for (
      size_t i = 
      0; i < N; ++i)
     
    
- 
    
     
    
    
     
          {
     
    
- 
    
     
    
    
     
              std::string ur1 = 
      "https://www.cnblogs.com/-clq/archive/2012/05/31/2528153.html";
     
    
- 
    
     
    
    
     
              ur1 += std::
      to_string(
      1234 + i);
     
    
- 
    
     
    
    
     
              v1.
      push_back(ur1);
     
    
- 
    
     
    
    
     
          }
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
         
      for (
      auto& str : v1)
     
    
- 
    
     
    
    
     
          {
     
    
- 
    
     
    
    
     
              bf.
      Set(str);
     
    
- 
    
     
    
    
     
          }
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
         
      for (
      auto& str : v1)
     
    
- 
    
     
    
    
     
          {
     
    
- 
    
     
    
    
     
              cout << bf.
      Test(str) << endl;
     
    
- 
    
     
    
    
     
          }
     
    
- 
    
     
    
    
     
          cout << endl << endl;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          std::vector<std::string> v2;
     
    
- 
    
     
    
    
         
      for (
      size_t i = 
      0; i < N; ++i)
     
    
- 
    
     
    
    
     
          {
     
    
- 
    
     
    
    
     
              std::string ur1 = 
      "https://www.cnblogs.com/-clq/archive/2012/05/31/2528153.html";
     
    
- 
    
     
    
    
     
              ur1 += std::
      to_string(
      6789 + i);
     
    
- 
    
     
    
    
     
              v2.
      push_back(ur1);
     
    
- 
    
     
    
    
     
          }
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
         
      size_t n2 = 
      0;
     
    
- 
    
     
    
    
         
      for (
      auto& str : v2)
     
    
- 
    
     
    
    
     
          {
     
    
- 
    
     
    
    
             
      if (bf.
      Test(str))
     
    
- 
    
     
    
    
     
              {
     
    
- 
    
     
    
    
     
                  ++n2;
     
    
- 
    
     
    
    
     
              }
     
    
- 
    
     
    
    
     
          }
     
    
- 
    
     
    
    
     
          cout << 
      "相似字符串误判率:" << (
      double)n2 / (
      double)N << endl;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
          std::vector<std::string> v3;
     
    
- 
    
     
    
    
         
      for (
      size_t i = 
      0; i < N; ++i)
     
    
- 
    
     
    
    
     
          {
     
    
- 
    
     
    
    
     
              string ur1 = 
      "zhihu.com";
     
    
- 
    
     
    
    
             
      //std::string ur1 = "https://mail.qq.com/cgi-bin/frame_html?sid=0QvJ6bvfhn3EC1Iw&r=5976c09322eae24513a5ff315428cd86&lang=zh";
     
    
- 
    
     
    
    
             
      //std::string ur1 = "https://www.sogou.com/tx?query=%E5%88%98%E5%BC%BA%E4%B8%9C%E4%BA%8B%E4%BB%B6%20%E5%A5%B3%E6%96%B9%E7%A7%B0%E8%87%AA%E6%84%BF%E5%8F%91%E7%94%9F%E5%85%B3%E7%B3%BB&hdq=sogou-site-706608cfdbcc1886&ekv=3&ie=utf8&";
     
    
- 
    
     
    
    
             
      //std::string ur1 = "https://www.sogou.com/sogou?ie=utf8&pid=sogou-wsse-af64b05ee108fa0c&query=%E4%BA%BA%E6%B0%91%E7%BD%91%3A%E5%BE%B7%E4%BA%91%E7%A4%BE%E8%AF%A5%E8%87%AA%E6%88%91%E6%A3%80%E8%A7%86%E4%BA%86";
     
    
- 
    
     
    
    
     
              ur1 += std::
      to_string(
      rand());
     
    
- 
    
     
    
    
     
              v3.
      push_back(ur1);
     
    
- 
    
     
    
    
     
          }
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
         
      size_t n3 = 
      0;
     
    
- 
    
     
    
    
         
      for (
      auto& str : v3)
     
    
- 
    
     
    
    
     
          {
     
    
- 
    
     
    
    
             
      if (bf.
      Test(str))
     
    
- 
    
     
    
    
     
              {
     
    
- 
    
     
    
    
     
                  ++n3;
     
    
- 
    
     
    
    
     
              }
     
    
- 
    
     
    
    
     
          }
     
    
- 
    
     
    
    
     
          cout << 
      "不相似字符串误判率:" << (
      double)n3 / (
      double)N << endl;
     
    
- 
    
     
    
    
     
      }
     
    

设置为1
首先先用三个哈希函数算出对应的下标

再复用前面的位图的函数将其bit位设为1即可
 
注意:当len越大时,即空间开的越大时,误判率会越低
检查在不在
三个bit位,只要有一个bit位为0,则表示不在

注意:布隆过滤器不支持删除,因为支持删除会消耗很多空间,而且会存在误删,比如上图中的ate和eat,如果删除ate,那就会改变eat中的其中一个bit位
哈希切割
例:给两个文件,分别有100亿个query,我们只有1G内存,如何找到两个文件交集?分别给出精确算法和近似算法,这里就要用到哈希切割

注意:如果Ai和Bi都太大,可以考虑换个哈希函数,再切割一次
全部代码
转载:https://blog.csdn.net/weixin_58867976/article/details/125464703
