欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

暴雪的哈希算法 -

系統 1631 0
暴雪公司有個經典的字符串的hash公式

先提一個簡單的問題,假如有一個龐大的字符串數組,然后給你一個單獨的字符串,讓你從這個數組中查找是否有這個字符串并找到它,你會怎么做?

有一個方法最簡單,老老實實從頭查到尾,一個一個比較,直到找到為止,我想只要學過程序設計的人都能把這樣一個程序作出來,但要是有程序員把這樣的程序交給用戶,我只能用無語來評價,或許它真的能工作,但...也只能如此了。

最合適的算法自然是使用HashTable(哈希表),先介紹介紹其中的基本知識,所謂Hash,一般是一個整數,通過某種算法,可以把一個字符串"壓縮" 成一個整數,這個數稱為Hash,當然,無論如何,一個32位整數是無法對應回一個字符串的,但在程序中,兩個字符串計算出的Hash值相等的可能非常小,下面看看在MPQ中的Hash算法

unsigned long HashString(char *lpszFileName, unsigned long dwHashType)
{
unsigned char *key = (unsigned char *)lpszFileName;
unsigned long seed1 = 0x7FED7FED, seed2 = 0xEEEEEEEE;
int ch;

while(*key != 0)
{
ch = toupper(*key );

seed1 = cryptTable[(dwHashType < < ch] ^ (seed1 seed2);
seed2 = ch seed1 seed2 (seed2 < < 5) 3;
}
return seed1;
}

Blizzard的這個算法是非常高效的,被稱為"One-Way Hash",舉個例子,字符串"unitneutralacritter.grp"通過這個算法得到的結果是0xA26067F3。
是不是把第一個算法改進一下,改成逐個比較字符串的Hash值就可以了呢,答案是,遠遠不夠,要想得到最快的算法,就不能進行逐個的比較,通常是構造一個哈希表(Hash Table)來解決問題,哈希表是一個大數組,這個數組的容量根據程序的要求來定義,例如1024,每一個Hash值通過取模運算 (mod)對應到數組中的一個位置,這樣,只要比較這個字符串的哈希值對應的位置又沒有被占用,就可以得到最后的結果了,想想這是什么速度?是的,是最快的O(1),現在仔細看看這個算法吧

int GetHashTablePos(char *lpszString, SOMESTRUCTURE *lpTable, int nTableSize)
{
int nHash = HashString(lpszString), nHashPos = nHash % nTableSize;

if (lpTable[nHashPos].bExists && !strcmp(lpTable[nHashPos].pString, lpszString))
return nHashPos;
else
return -1; //Error value
}

看到此,我想大家都在想一個很嚴重的問題:"假如兩個字符串在哈希表中對應的位置相同怎么辦?",究竟一個數組容量是有限的,這種可能性很大。解決該問題的方法很多,我首先想到的就是用"鏈表",感謝大學里學的數據結構教會了這個百試百靈的法寶,我碰到的很多算法都可以轉化成鏈表來解決,只要在哈希表的每個入口掛一個鏈表,保存所有對應的字符串就OK了。

事情到此似乎有了完美的結局,假如是把問題獨自交給我解決,此時我可能就要開始定義數據結構然后寫代碼了。然而Blizzard的程序員使用的方法則是更精妙的方法。基本原理就是:他們在哈希表中不是用一個哈希值而是用三個哈希值來校驗字符串。

中國有句古話"再一再二不能再三再四",看來Blizzard也深得此話的精髓,假如說兩個不同的字符串經過一個哈希算法得到的入口點一致有可能,但用三個不同的哈希算法算出的入口點都一致,那幾乎可以肯定是不可能的事了,這個幾率是1:18889465931478580854784,大概是10的 22.3次方分之一,對一個游戲程序來說足夠安全了。

現在再回到數據結構上,Blizzard使用的哈希表沒有使用鏈表,而采用"順延"的方式來解決問題,看看這個算法:
int GetHashTablePos(char *lpszString, MPQHASHTABLE *lpTable, int nTableSize)
{
const int HASH_OFFSET = 0, HASH_A = 1, HASH_B = 2;
int nHash = HashString(lpszString, HASH_OFFSET);
int nHashA = HashString(lpszString, HASH_A);
int nHashB = HashString(lpszString, HASH_B);
int nHashStart = nHash % nTableSize, nHashPos = nHashStart;

while (lpTable[nHashPos].bExists)
{
if (lpTable[nHashPos].nHashA == nHashA && lpTable[nHashPos].nHashB == nHashB)
return nHashPos;
else
nHashPos = (nHashPos 1) % nTableSize;

if (nHashPos == nHashStart)
break;
}

return -1; //Error value
}

1. 計算出字符串的三個哈希值(一個用來確定位置,另外兩個用來校驗)
2. 察看哈希表中的這個位置
3. 哈希表中這個位置為空嗎?假如為空,則肯定該字符串不存在,返回
4. 假如存在,則檢查其他兩個哈希值是否也匹配,假如匹配,則表示找到了該字符串,返回
5. 移到下一個位置,假如已經越界,則表示沒有找到,返回
6. 看看是不是又回到了原來的位置,假如是,則返回沒找到
7. 回到3

暴雪的哈希算法 -


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 美女午夜色视频在线观看 | 国产精品国偷自产在线 | 4hu四虎永久免在线视看 | 亚洲午夜成激人情在线影院 | 色网在线播放 | 欧美手机在线观看 | 午夜在线小视频 | 日韩专区中文字幕 | 成人毛片在线播放 | 伦理一区二区 | a网站在线观看 | 在线视频国产一区 | 黄色羞羞视频在线观看 | 欧美日韩三区 | 成人免费观看网欧美片 | 黄色av片在线观看 | 日韩一区二区不卡 | 一区二区高清在线观看 | 欧美网站www | 亚洲国产日韩a在线亚洲 | 一级毛片 在线播放 | 日韩在线观看免费 | 久久影片 | 中国大陆高清aⅴ毛片 | 免费在线一级毛片 | 国产精品美女久久久久久久网站 | 99热热热 | 青草草在线观看免费视频 | 国产福利资源在线 | 国产精品亚洲va在线观看 | 男人天堂中文字幕 | 国产在线观看福利片 | 成人午夜视频在线观看 | 久草视频福利在线观看 | av激情影院 | 小明成人永久视频在线观看 | 亚洲第一视频 | 国产精品毛片大码女人 | 精品国产一区二区三区香蕉沈先生 | 日韩一级欧美一级毛片在线 | 暴操美女视频 |