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

A way to store keys in a dictionary without storing the key?

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

有时键很长,而且通常是字符串,所以每个键可以超过 40 个字节,而如果它只是一个哈希码。如果存储的密钥是​​经过哈希处理的对象,但使用略有不同的哈希算法,具有不同的质数,会怎样?那么发生碰撞的几率就是 (1/(2^32)) * (1/(2^32)).

您甚至可以使用另一种散列算法并存储该散列,因此发生冲突的可能性为 (1/(2^32)) * (1/(2^32)) * (1/(2^32))。显然,冲突仍然可能发生,但几率非常低,而且您只需为密钥存储 4 个字节而不是超过 32 个字节,就可以节省大量内存。

我想这仍然是不可接受的,对吧,因为仍然有机会,但也有可能有人的 RAM 不小心翻转了一下并出现蓝屏,这似乎不太可能,所以不实施是很有诱惑力的。有没有其他选择,还是这个小机会仍然不值得?

如果您想 100% 确定没有任何冲突,则无法在插入前检查密钥。话虽这么说,我们在这里很幸运,因为实现良好的词典正是您快速找到密钥所需要的。

话虽如此,您可能想看一下 here 中描述的函数。碰撞几率会很低

编辑:删除了我写的关于 GUID 的一些废话...

视情况而定。

绝对需要保证冲突解决吗?如果是这样:您必须存储密钥或与其等效的东西。在某些情况下(例如小密钥空间、冗​​余数据等),您可以使用压缩或自定义哈希函数 可逆地 将密钥映射到更小的内容。

如果不是:是的,您的方法会奏效。注意,由于birthday paradox,发生碰撞的概率为:

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

需要权衡:现在您必须计算(并比较)多个哈希值才能找到项目。

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

除了最高性能 and/or 内存受限的应用程序之外,大多数这对所有应用程序来说都是矫枉过正 - 但它 偶尔 做这样的事情很有用 :)