一种在不存储密钥的情况下将密钥存储在字典中的方法?

时间:2015-03-03 19:51:34

标签: c# algorithm dictionary hash hashcode

例如,如果编写字典类,碰撞很少见,但它们确实存在。因此,您需要存储密钥以确保在哈希表中找到密钥时,它是正确的,而不是冲突。

有时密钥很长并且它们通常是字符串,因此每个密钥可以超过40个字节,而不是它只是一个哈希代码。如果存储的密钥是​​对象已经散列但使用稍微不同的散列算法,具有不同的素数会怎么样?然后发生碰撞的可能性为(1/(2^32)) * (1/(2^32))

您甚至可以使用其他哈希算法并存储该哈希值,因此冲突的可能性为(1/(2^32)) * (1/(2^32)) * (1/(2^32))。显然,碰撞可能仍然会发生,但机会很低,只需要为密钥存储4个字节而不是超过32个字节,就可以节省大量内存。

我想这仍然是不可接受的,但是,因为它仍然是一个机会,但也有可能某人的内存不小心翻了一下蓝屏,这只是似乎不太可能没有实施。有没有其他选择,还是小机会仍然不值得?

2 个答案:

答案 0 :(得分:2)

如果您想100%确定没有任何碰撞,那么在插入之前无法检查钥匙。话虽这么说,我们在这里很幸运,因为一个很好实现的词典正是你需要的,以便快速找到一个密钥。

话虽这么说,你可能想看一下here所描述的功能。碰撞机会相当低

编辑:删除了我写的关于GUID的一些无意义......

答案 1 :(得分:1)

取决于。

绝对需要保证冲突解决吗?如果是这样的话:你必须存储密钥或类似的东西。在某些情况下(例如小键空间,冗余数据等),您可以使用压缩或自定义散列函数来可逆地将键映射到更小的键。

如果不是:是的,你的方法会起作用。请注意,由于birthday paradox,碰撞的概率为:

  • 取决于集合中已有的元素数量;和
  • 比你想象的更高。

有一个权衡:现在你必须计算(和比较)几个哈希才能找到项目。

继续沿着这条路走下去:为什么有一定数量的哈希?你可以计算一个哈希值,只有在发生冲突时才计算下一个哈希值;这导致了基于特里的实现。 (当然,您需要一个可靠分布的系列哈希函数...)

对于除了最高性能和/或内存受限的应用程序之外的所有应用程序来说,大多数情况都是过度的 - 但是偶尔对于执行这样的操作非常有用:)