暴雪Hash表实现与测试

来源:互联网 发布:java下载网页源代码 编辑:程序博客网 时间:2024/05/22 05:24

StringHash.H

#ifndef __STRING_HASH_H__#define __STRING_HASH_H__// Definition of MPQHashTablestruct MPQHashTable{long nHashA;long nHashB;bool bExists;};#define   CRYPT_TABLE_LENGTH  (256 * 5)#define   MAX_TABLE_LENGTH    1024class StringHash{private:unsigned long m_pCryptTable[CRYPT_TABLE_LENGTH];unsigned long m_nTableLength;MPQHashTable* m_pHashTable;private:void InitCryptTable();unsigned long HashString(const char* lpszString, unsigned long hashType);public:StringHash(unsigned long tableLength = MAX_TABLE_LENGTH);~StringHash();bool Hash(const char* lpszString);unsigned long Hashed(const char* lpszString);unsigned long getHashTableLength();};#endif

StringHash.CPP

#include "StringHash.h"#include <ctype.h>#include <stdlib.h>// Initialize the crypt arrayvoid StringHash::InitCryptTable(){unsigned long seed = 0x00100001;for (int i = 0; i < 256; ++i){for (int j = i, k = 0; k < 5; ++k, j += 256){seed = (seed * 125 + 3) % 0x2AAAAB;unsigned long tmp = (seed & 0xFFFF) << 0x10;seed = (seed * 125 + 3) % 0x2AAAAB;m_pCryptTable[j] = tmp | (seed & 0xFFFF);}}}StringHash::StringHash(unsigned long tableLength){m_nTableLength = tableLength;m_pHashTable = new MPQHashTable[m_nTableLength];InitCryptTable();for (unsigned long i = 0; i < m_nTableLength; ++i){m_pHashTable[i].nHashA = -1;m_pHashTable[i].nHashB = -1;m_pHashTable[i].bExists = false;}}StringHash::~StringHash(){if (NULL != m_pHashTable){delete[] m_pHashTable;m_pHashTable = NULL;m_nTableLength = 0;}}// The one-way hash functionunsigned long StringHash::HashString(const char*lpszString, unsigned long hashType){unsigned char* key = (unsigned char*)lpszString;unsigned long seed1 = 0x7FED7FED, seed2 = 0xEEEEEEEE;int ch;while (*key != 0){ch = toupper(*key++);seed1 = m_pCryptTable[hashType << 8] ^ (seed1 + seed2);seed2 = ch + seed1 + seed2 + (seed2 << 5) + 3;}return seed1;}// Hash a string to the hash tablebool StringHash::Hash(const char* lpszString){const unsigned long HASH_OFFSET = 0, HASH_A = 1, HASH_B = 2;unsigned long nHash = HashString(lpszString, HASH_OFFSET);unsigned long nHashA = HashString(lpszString, HASH_A);unsigned long nHashB = HashString(lpszString, HASH_B);unsigned long nHashStart = nHash % m_nTableLength;unsigned long nHashPos = nHashStart;while (m_pHashTable[nHashPos].bExists){nHashPos = (nHashPos + 1) % m_nTableLength;if (nHashPos == nHashStart){return false;}}m_pHashTable[nHashPos].bExists = true;m_pHashTable[nHashPos].nHashA = nHashA;m_pHashTable[nHashPos].nHashB = nHashB;return true;}// Find a string in the hash table, if it exists then return// the index of the string, else return -1unsigned long StringHash::Hashed(const char* lpszString){const unsigned long HASH_OFFSET = 0, HASH_A = 1, HASH_B = 2;unsigned long nHash = HashString(lpszString, HASH_OFFSET);unsigned long nHashA = HashString(lpszString, HASH_A);unsigned long nHashB = HashString(lpszString, HASH_B);unsigned long nHashStart = nHash % m_nTableLength;unsigned long nHashPos = nHashStart;while (m_pHashTable[nHashPos].bExists){if (m_pHashTable[nHashPos].nHashA == nHashA && m_pHashTable[nHashPos].nHashB == nHashB){return nHashPos;}else{nHashPos = (nHashPos + 1) % m_nTableLength;}if (nHashPos == nHashStart){break;}}return -1;}unsigned long StringHash::getHashTableLength(){return m_nTableLength;}

测试函数:

#include "StringHash.h"#include <iostream>using namespace std;int main(){char* str1 = "StringHash.h";char* str2 = "StringHash.cpp";StringHash hasher(20);cout << "Length of Hash Table: " << hasher.getHashTableLength() << endl;cout << "Hash \"" << str1 << "\": " << boolalpha << hasher.Hash(str1) << endl;cout << "Hash \"" << str2 << "\": " << boolalpha << hasher.Hash(str2) << endl;cout << "Checking ..." << endl;cout << "Position of \"" << str1 << "\": " << hasher.Hashed(str1) << endl;cout << "Position of \"" << str1 << "\": " << hasher.Hashed(str2) << endl;return 0;}

参考:http://sfsrealm.hopto.org/inside_mopaq/chapter2.htm

原创粉丝点击