• 哈希-------开放寻址法-------暴雪哈希


     1 //StringHash.h
     2 
     3 #ifndef __STRINGHASH__                                                                                             
     4 #define __STRINGHASH__
     5 
     6 #define MAXTABLELEN 1024 //默认哈希索引表大小
     7 
     8 //哈希索引表定义
     9 typedef struct _HASHTABLE
    10 {
    11     long nHashA; 
    12     long nHashB; 
    13     bool bExists;
    14 }HASHTABLE, *PHASHTABLE;
    15 
    16 class StringHash
    17 {
    18     private:
    19         unsigned long cryptTable[0x500];
    20         unsigned long m_tablelength;
    21         HASHTABLE *m_HashIndexTable;
    22     
    23     private:
    24         InitCryptTable(); //对哈希索引表预处理
    25 
    26         unsigned long HashString(const char* lpszString, unsigned long dwHashType); //求取哈希值
    27     
    28     public: 
    29         StringHash(const long nTableLength = MAXTABLELEN);
    30         ~StringHash(void);
    31 
    32         bool Hash(const char* url);
    33         unsigned long Hashed(const char* url); //检测url是否被hash过
    34 };
    35 
    36 #endif
      1 //StringHash.cpp
      2 
      3 #include <StringHash.h>                                                                                            
      4 
      5 StringHash::StringHash(const long nTableLength)
      6 {
      7     InitCryptTable();
      8     m_tablelength = nTableLength;
      9 
     10     //初始化hash表
     11     m_HashIndexTabel = new HASHTABLE[nTableLength];
     12     for(int i = 0; i < nTableLength; i++)
     13     {
     14         m_HashIndexTable[i].nHashA = -1;
     15         m_HashIndexTable[i].nHashB = -1;
     16         m_HashIndexTable[i].bExists = false;
     17     }
     18 }
     19 
     20 StringHash::~StringHash(void)
     21 {
     22     //清理内存
     23     if(NULL != m_HashIndexTable)
     24     {
     25         delete []m_HashIndexTable;
     26         m_HashIndexTable = NULL; 
     27         m_tablelength = 0;
     28     }
     29 }
     30 
     31 /*
     32  *函数名:InitCryptTable
     33  *功  能:对哈希索引表预处理
     34  *返回值:无
     35  */
     36 void StringHash::InitCryptTable(void)
     37 {
     38     unsigned long sedd = 0x00100001,
     39                   index1 = 0,
     40                   index2 = 0,
     41                   i = 0;  
     42     for(index1 = 0; index1 < 0x100; index1++)
     43     {
     44         for(index2 = index1, i = 0; i < 5; i++, index2 += 0x100)
     45         {
     46             unsigned long temp1, temp2;
     47             seed = (seed * 125 + 3) % 0X2AAAAB;
     48             temp1 = (seed & 0XFFFF) << 0X10;
     49             seed = (seed * 125 + 3) % 0X2AAAAB;
     50             temp2 = (seed & 0XFFFF);
     51             cryptTable[index2] = (temp1 | temp2);
     52         }
     53     }
     54 }
     55 
     56 /*
     57  *函数名:HashString
     58  *功  能:求取哈希值
     59  *返回值:返回hash值
     60  */
     61 unsigned long StringHash::HashString(const char* lpszString, unsigned long dwHashType)
     62 {
     63     unsigned char* key = lpszString;
     64     unsigned long seed1 = 0X7FED7FED,
     65                   seed2 = 0XEEEEEEEE;
     66     int ch = 0;
     67     while(*key != 0)
     68     {
     69         ch = toupper(*key++);
     70         seed1 = cryptTable[(dwHashType << 8) + ch] ^ (seed1 + seed2);
     71         seed2 = ch + seed1 + seed2 + (seed2 << 5) + 3;
     72     }
     73     return seed1;
     74 }
     75 
     76 /*
     77  *函数名:Hashed
     78  *功  能:检测一个字符串是否被hash过
     79  *返回值:如果存在,返回位置;否则,返回-1
     80  */
     81 unsigned long StringHash::Hashed(const char* lpszString)
     82 {
     83     const unsigned long HASH__OFFSET = 0, HASH_A = 1, HASH_B = 2;
     84     //不同的字符串三次hash还会碰撞的概率无限接近于0
     85     unsigned long nHash = HashString(lpszString, HASH_OFFSET);
     86     unsigned long nHashA = HashString(lpszString, HASH_A);
     87     unsigned long nHashB = HashString(lpszString, HASH_B);
     88     unsigned long nHashStart = nHash % m_tablelength;
     89     unsigned long nHashPos = nHashStart;
     90 
     91     while(m_HashIndexTable[nHashPos].bExists)
     92     {
     93         if(m_HashIndexTable[nHashPos].nHashA == nHashA &&
     94            m_HashIndexTable[nHashPos].nHashB == nHashB)
     95             return nHashPos;
     96         else
     97             nHashPos = (nHashPos + 1) % m_tablelength;
     98 
     99         if(nHashPos == nHashStart)
    100             break;
    101     }
    102 
    103     return -1;
    104 }
    105 
    106 /*
    107  *函数名:Hash
    108  *功  能:hash一个字符串
    109  *返回值:成功,返回true; 失败, 返回false
    110  */
    111 bool StringHash::Hash(const char* lpszString)
    112 {
    113     const unsigned long HASH_OFFSET = 0, HASH_A = 1, HASH_B = 2;
    114     unsigned long nHash = HashString(lpszString, HASH_OFFSET);
    115     unsigned long nHashA = HashString(lpszString, HASH_A);
    116     unsigned long nHashB = HashString(lpszString, HASH_B);
    117     unsigned long nHashStart = nHash % m_tablelength;
    118     unsigned long nHashPos = nHashStart;
    119 
    120     while(m_HashIndexTable[nHashPos].bExists)
    121     { 
    122         nHashPos = (nHashPos + 1) % m_tablelength;
    123         if(nHashPos == nHashStart) //一个轮回
    124         {
    125             //hash表中没有空余的位置了,无法完成hash
    126             return false;
    127         }
    128     }
    129 
    130     m_HashIndexTable[nHashPos].bExists = true;
    131     m_HashIndexTable[nHashPos].nHashA = nHashA;
    132     m_HashIndexTable[nHashPos].nHashB = nHashB;
    133 
    134     return true;
    135 }                               
  • 相关阅读:
    dell r720服务器raid5安装centos6.5系统
    centos6.5报错:checking filesystems failed问题处理
    配置mysql5.5主从复制、半同步复制、主主复制
    vmware下centos克隆功能对网络的设置
    mysql报错问题解决MySQL server PID file could not be found!
    使用第三方工具Xtrabackup进行MySQL备份
    mysql数据库基于LVM快照的备份
    mysql的日志及利用mysqldump备份及还原
    centos6.5下java和tomcat环境部署
    通达OA数据库优化方案之_历史数据清理
  • 原文地址:https://www.cnblogs.com/openix/p/3175409.html
Copyright © 2020-2023  润新知