1. 程式人生 > >為什麼Hash函式 H(k) = k % m中 m 儘量不要為2的冪次 也不是要是2^i -1

為什麼Hash函式 H(k) = k % m中 m 儘量不要為2的冪次 也不是要是2^i -1

為什麼Hash函式 H(k) = k % m中 m 儘量不要為2的冪次

下面的截圖來自CLRS的11章 關於雜湊函式的討論


之前我就一直困惑,為什麼

            When using the division method, we usually avoid certain values of m. For example, m should not be a power of 2, since ifm = 2^p, then H(k) is just the p lowest-order bits ofk. Unless we know that all low-order p-bit patterns are equally likely, we are better off designing the hash function to depend on all the bits of the key.

-----------------------------------------------------------------------------------------------------------

為嘛就是儘量要避免 k%m中m不要是2的冪次呢?

如果2的i次冪 2^i = 10... .... 0 從1後面的第一個0開始到結束,一共有i個0

如果用k%m進行取餘數操作,m = 2^i, 結果就是把k 截斷保留低位的i位。這對於hash來說,是很“糟糕的特性”

問題的根結在於hash要有很好的特性,就是要避免碰撞,避免碰撞就要分佈均勻的插入

直接的截斷是很粗魯的方式,無法保證插入資料能夠均勻的分佈於hash table中。

-----------------------------------------------------------------------------------------------------------

為嘛就是要避免k %m 中m不要是2冪次-1呢(2^i -1)?

對於不同的字串S1 = “abcd” S2 = "adcb"

他們的hash值是相同的!但是他們是不同的字串!他們會衝突!

怎麼辦呢?考慮字串中的單個字元的順序,對各個字串進行加權,而加權的具體方式就是他們所處於字串中的位。比方說字串

S1 求值可以這樣 'a'*2^(0) + 'b'* (2^(1)) + 'c' * (2^2) + 'd' * (2^3)

S2 求值可以這樣 'a'*2^(0) + 'd'* (2^(1)) + 'c' * (2^2) + 'b' * (2^3) 

兩者的字面值就不一樣了。這樣就完了?可以確保不會衝突? 沒完呢。。。

證明很酷帥




       攝於 二零一五年一月五日 晚.