Hash學習(2) Hash函式

2021-06-02 01:43:41 字數 1407 閱讀 1933

乙個好的hash函式一般具有以下兩個特點:第一,速度快,第二,能夠將雜湊鍵均勻的分布在整個表中,保證不會產生聚集。通常,hash函式具有如下形式:

hash-key = calculated-key % tablesize

上一節主要討論了一下tablesize,為了提高雜湊鍵的離散程度,tablesize通常取素數。一般而言,沒有絕對好的hash函式,hash函式的好壞很大程度上依賴於輸入鍵的結構,人們討論的最多的一般都是輸入鍵為普通字串的情況。這裡也以字串為例討論如何一步步優化hash函式。

當鍵是字串時,一種選擇策略是簡單的將字串中每個字元的ascii碼加起來,**如下:

unsigned int hash(const char *key, unsigned int tablesize)

上面的hash函式實現簡單而且能夠很快的算出答案,不過,如果表很大,則函式就不能很好的分配鍵,例如,設tablesize=10949,並設所有的鍵至多8個字元長,由於ascii字元的值最多是127,因此hash函式只能在0~1016之間取值,其中1016為127*8,顯然這不是一種均勻的分配。

下面的hash函式對針對上面的缺點進行了改進。

unsigned int hash(const char *key, unsigned int tablesize)

這個hash函式假設key至少有3個字元。值27表示英文本母表的字母個數外加乙個空格,而729是27的平方。雖然該函式只考察了前三個字元,但是,假如字元出現的概率是隨機的,而表的大小還是10949,那麼我們就會得到乙個合理的均衡分布。可是,英文不是隨機的。雖然3個字元有26*26*26=17567種可能的組合,但查驗詞彙量足夠大的聯機詞典卻揭示出:3個字母的不同組合數實際上只有2851種。即使這些組合沒有衝突,也不過只有表的28%被真正雜湊到。因此,雖然容易計算,但是當hash表足夠大的時候,這個函式還是不合適。

針對以上缺點,進一步改進:

unsigned int hash(const char *key,unsigned int tablesize)

這個hash函式涉及鍵中的所有字元,並且一般可以分布的很好,它計算了字串的如下值:

在計算該值時,利用了horner法則,例如計算 hash=a+32b+32*32c 的另一種方式是借助公式:hash=((c)*32+b)*32+a。horner法則將其擴充套件到用於n次多項式。該演算法通過將乘法運算轉換為位運算保證了hash函式快速的特點。

下面給出實際字串hash應用中使用的很廣的乙個hash函式:elfhash

unsigned long elfhash(const unsigned char * key)

return h;

}

Hash函式和Hash衝突

2.rehash 3.鍊錶法 4.建立公共溢位區 一 簡介 將任意長度的數值以某個對映規則對映為固定長度的數值,這個過程稱為hash,而這個對映規則被稱為hash函式,而對這個key value進行儲存的資料結構被稱為hash表。由於通過key的hash對映直接得到了記憶體位址,所以hash查詢的時...

各種hash 函式

常用的字串hash函式還有elfhash,aphash等等,都是十分簡單有效的方法。這些函式使用位運算使得每乙個字元都對最後的函式值產生影響。另外還有以md5和sha1為代表的雜湊函式,這些函式幾乎不可能找到碰撞。常用字串雜湊函式有 bkdrhash,aphash,djbhash,jshash,rs...

hash函式解析

hash函式在多個領域均有應用,而在數字簽名和資料庫實現時又用的最多,比如基於hash的索引,是最好的單值查詢索引 同時,在當前資料 的場景下,執行相似item的查詢時,在記憶體受限時,均可以採取lsh local sensitive hash 進行分段處理。具體用途很多,不贅述,下面介紹一些常用的...