1
5
我在cstheory.stackexchange.com上问了同样的问题,得到了一个很好的答案: |
2
2
反转位。例如,0000101变为11010000。然后,对所有反转的集合元素求和。 如果在insert/delete上需要O(1),那么通常的SUM就可以工作(这就是用Java实现集合的方式),尽管在小整数集合上分布不好。 如果我们的集合不是均匀分布的(通常是这样),我们需要映射N->f(N),以便f(N)对于预期的数据样本是均匀分布的。通常,数据样本比接近最大数字更接近零个数。在这种情况下,反向位散列将均匀地分布它们。 Scala中的示例:
但是我们的多重集合的散列不会是一致的,尽管比简单的和要好得多。 |
3
2
我同意Dzmitry关于散列算术和的使用,但我建议使用一个散列函数,它对输入整数具有良好的输出分布,而不仅仅是反转整数中的位。反转位并不能改善输出分布。它甚至会恶化输出分布,因为在这种情况下,由于和溢出而丢失高阶位的概率比丢失低阶位的概率高得多。下面是一个具有良好输出分布的快速哈希函数示例: http://burtleburtle.net/bob/c/lookup3.c . 还请阅读描述哈希函数必须如何构造的论文- http://burtleburtle.net/bob/hash/evahash.html . 使用集合中每个元素的哈希值之和满足问题中的要求:
SUM和SUB是面对整数溢出的安全操作,因为它们在 modular arithmetic ,其中,对于java中的整数,模数为2^32或2^64。 |
4
0
Knuth在TAoCP上提到了这个,这是 What integer hash function are good that accepts an integer hash key? . 对于您的情况,将多个集合转换为单个整数,然后执行链接post中描述的散列可能是您想要做的。把一个集合转换成一个数字是微不足道的;数字的串联就可以了。 有关Knuth方法的更多信息,请搜索“Knuth的乘法方法” -tjw公司 |
5
0
最小散列应该在这里工作。应用置换,保持n个最小元素的一个小多集,选择最大的。 阐述:这是一种在O(1)时空中工作的简单方法。您需要类似于优先级队列的东西,而不需要使到初始值的链接过于明显。因此,您可以根据某个精心编制的键对优先级队列进行排序,这相当于在正常排序顺序的排列上运行优先级队列。使队列跟踪多重性,以便所选元素也形成多重集。 也就是说,我不确定这种分散是否足够好(并且运行多个排列可能会变得昂贵),所以也许可以建立在布拉德利的答案上。这里有一个调整,以便重复的元素不会取消:
|
6
0
我曾经问过类似的问题 Good hash function for permutations? “,并且得到了一个对我的用例非常有效的散列,我的工作代码中很少有冲突。也许对你也有好处。计算如下:
所以每当你加上一个数字
当你想合并两个集合时,只需乘以散列值。 我唯一不确定的是是否有可能删除O(1)中的值。 |
danial · 如何在多个字符串的每个位置找到最频繁的字符 1 年前 |
Manny · 如何比较Perl中的字符串? 2 年前 |
Diret · 获取范围内每个数字的子倍数的算法 2 年前 |
Saif · 排序时python如何决定何时调用比较器? 2 年前 |