【发布时间】:2018-01-23 00:41:40
【问题描述】:
我有一个 4 维 Point 类,其中 4 个值中的每一个都是介于 0 到大约 1000 之间的整数,因此此类 Point 上的散列函数将返回从 0 到 1000^4 的值,因此需要 40 位如果我的数学是正确的。但是,我必须重写的 GetHashCode 方法(散列函数)只能返回 32 位整数; 40 位整数还不够。
我的最终目标是使用 HashSet 来检查列表中重复的 4D 点,方法是遍历所有这些点并将它们添加到 HashSet(如果该索引处已经有一个元素,则该点已经被看到并且是重复的)。 这意味着哈希集中的索引与哈希点的值一样多,即 1000^4 个不同的索引。
将放入哈希集中的实际点数最多为 8,000。每次尝试将一个点插入哈希集中时,预计会发生 0 或 1 次冲突(再也不会发生)。
请原谅我可能对 HashSets 的误解。我对我的算法的运行时间不太在意,但我正在尝试看看它的“大哦”时间成本会有多低。
【问题讨论】:
-
HashSet 要求您使用 32 位散列。对于具有相同哈希的不相等集合元素,它没有任何问题。一个明显的实现是 return v1 ^ (v2
-
请记住,哈希函数的设计目的是减少冲突,而不是完全消除冲突。有远远超过 40 亿个短字符串,但不知何故,字符串哈希表在 32 位哈希上就可以了。这是因为碰撞非常罕见。散列不能代替相等检查;相反,它加快了相等性检查,因为您只需对冲突进行完全相等性检查。
-
@EricLippert 虽然我认为它会从 O(1) 移动到 O(n),但我只是希望从 32 位到 40 位的轻微增加仍然会有一些 O(1 ) 解决方案。
-
@TeeMee123 这是 O(n),其中 n 是每个对象的平均碰撞次数,而不是*集合的大小。在您的情况下,每个对象的平均碰撞次数几乎可以肯定是一个常数,并且是一个非常小的常数,这使得哈希集在实践中具有 O(1) 操作。
-
这是一个与您提出的问题完全不同的问题。在 SO 上,我们称之为“XY 问题”。你对如何解决你的问题有一些完全疯狂的想法,然后你就这个疯狂的想法提出问题,导致每个人都说“这太疯狂了”。如果您的问题是“我如何为四个小整数的向量制作分布良好的哈希码”,那么问这个问题。