现在我有一些整数集,比如说:
set1 = {int1, int2, int3};
set2 = {int2, int3, int1};
set3 = {int1, int4, int2};
不考虑订单或数字,因此set1和set2相同,而set3与其他两个不相同。
现在我想为这些集生成一个唯一键来区分它们,这样,set1和set2应该生成相同的键。
我认为这有一段时间了,想到总结整数的想法出现在我脑海中,但很容易被证明是错误的。对集合进行排序并执行
key = n1 + n2*2^16 + n3*2^32
可能是一种可能的方式,但我想知道这是否可以更优雅地解决。 密钥可以是整数或字符串。
所以任何人都有尽快解决这个问题的想法?或欢迎任何阅读材料。
更多信息: 这些数字实际上是颜色,因此每个整数都小于0xffffff
答案 0 :(得分:0)
希望如果没有更好的想法,这将有助于您的解决方案。
答案 1 :(得分:0)
我认为实际大小的密钥只能是一个哈希值 - 总会有几对输入散列到同一个密钥,但你可以做到这一点。
我认为排序然后应用标准哈希函数的想法很好,但我不喜欢你的哈希乘数。如果算术是mod 2 ^ 32,则乘以2 ^ 32乘以零。如果它是mod 2 ^ 64,则乘以2 ^ 32将丢失输入的前32位。
我会使用像Why chose 31 to do the multiplication in the hashcode() implementation ?中描述的哈希函数,在这里你保持一个运行总计,将哈希值乘以一些奇数,然后再添加下一个项目。乘以奇数mod 2 ^ n将至少不会立即丢失信息。我建议131,但Java有使用31的传统。
答案 2 :(得分:0)
如果这些是小整数(例如,都在范围内(0,63))那么你可以将每个集合表示为一个位串(1表示集合中存在的任何整数; 0表示任何不存在的整数)。对于稀疏的大整数集,这在存储/存储方面会非常昂贵。
另一种想到的方法是对集合进行排序并将密钥形成为每个数字的数字表示的连接(由一些分隔符分隔)。所以集合{2,1,3} - > “1/2/3”(使用“/”作为分隔符)和{30,1,2,4} => “1/2/4/30”
我想你也可以使用混合方法。所有元素<如上所述,63被编码成十六进制字符串,所有其他字符串被编码成字符串。然后你的最终结果键由以下形成:HEXxA / B / c ...(“x”将小的int hex字符串与集合中较大的int分隔开。)