2013-04-12 20 views
1

根據http://java-bytes.blogspot.com/2009/10/hashcode-of-string-in-java.html:「首先,它是一個已知的事實,即沒有完美的哈希算法,沒有碰撞。」沒有這樣的東西作爲一個完美的散列函數?

作者談論實際而不是理論上正確的?因爲從理論上講,這裏是一個完美的散列函數:「對於一個給定的對象,給它賦一個新的數字」。有無數的數字,所以我們總是有東西分配給一個獨特的對象。實際上,這是不可行的,因爲我們的內存有限。

+1

您的「完美」功能如何確定「新號碼」是什麼? –

+0

除了在Java中(似乎是你的語言),散列是一個整數,它只能取2^32的值。 – assylias

+0

kenneth,這是不可能的在計算機上的原因解釋,但理論上它會是以前的哈希碼/數字+ 1 –

回答

8

通常,散列函數將一組對象(宇宙)映射到一組較小的對象(共域)。通常,宇宙是一個無限集合,例如所有字符串的集合或所有數字的集合,並且共域是有限集合,例如所有512位字符串的集合或0和一些數字k等等。在Java中,對象上的hashCode函數具有可以由所有32位整數的int表示的值的共域。

我相信,當作者說「沒有完美的散列函數」時,作者正在討論的是,沒有可能的方法將所有字符串的無限集合映射爲所有32位整數的集合,而沒有至少有一次碰撞。事實上,如果你選擇2 + 1個不同的字符串,你至少保證有一次碰撞。

你的論點 - 我們不能只爲每個對象分配不同的哈希碼嗎? - 暗示了散列函數的共域是無限的。例如,如果您要嘗試使用這種方法爲字符串構建散列函數,則散列函數的共域必須是所有可能的自然數的集合,因爲存在無限多的字符串。大多數編程語言不支持以這種方式工作的哈希代碼,儘管從理論上說這是可行的。當然,有人可能會反對並說這不算有效的散列函數,因爲通常散列函數具有有限的代碼。

希望這會有所幫助!

相關問題