【发布时间】:2015-05-04 15:09:01
【问题描述】:
例如,如果编写一个字典类,冲突是很少见的,但它们确实存在。因此,您需要存储密钥以确保当您在哈希表中找到您的密钥时,它是正确的,而不是冲突。
有时键很长并且通常是字符串,因此每个键可以超过 40 个字节,而如果它只是一个哈希码。如果存储的密钥是散列的对象,但使用稍微不同的散列算法,具有不同的素数怎么办?那么发生碰撞的可能性是(1/(2^32)) * (1/(2^32))。
您甚至可以使用另一种散列算法并存储该散列,因此发生冲突的可能性为(1/(2^32)) * (1/(2^32)) * (1/(2^32))。显然,仍然可能发生冲突,但可能性很小,而且您只需为密钥存储 4 个字节而不是超过 32 个字节,从而节省了大量内存。
我想这仍然是不可接受的,对,因为仍有机会,但也有可能某人的 RAM 可能会意外翻转一点并蓝屏,这似乎不太可能不实施。有没有其他选择,还是小机会仍然不值得?
【问题讨论】:
-
dictionary中的关键点是您有一个已知的唯一索引器,并且您希望找到存储在该索引处的值。如果你有一些只能从对象本身获取的现成哈希,你可能不需要字典,只需要一个列表。 -
如果你的哈希是 32 位,那么冲突的概率会比 1/2^32 高很多。每个这样的散列函数需要 4 个字节,因此其中 3 个需要 12 个字节。这么小的散列不太可能发生,所以如果你必须绝对避免冲突,我建议你留出 40 个字节。
-
你还假设了一个完美的散列函数,每个值的概率都具有完美的分布,这在现实中基本上是不可能的。
-
即使您存储了 6 个散列,每个散列使用不同的素数计算,它仍然比字符串键散列使用更少的内存,并且冲突的概率接近 10^50 分之一。我知道还有机会,而且散列并不完美,但看起来很诱人..
-
不,它不会是 10^50 中的 1。你从哪里得到这些数字?这比实际使用的可能性要大得多,具体取决于用于哈希的实际算法。
标签: c# algorithm dictionary hash hashcode