现在我有几组整数,比如说:
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也许是一种可能的方法,但我不知道是否可以更优雅地解决这一问题。键可以是整数,也可以是字符串。
所以有人想尽快解决这个问题吗?或者任何阅读材料都是受欢迎的。
更多信息:数字实际上是颜色,所以每个整数都小于0 0xffffff。
发布于 2015-03-10 05:58:23
如果这些是小整数(例如,都在范围内(0,63)),那么您可以将每个集合表示为一个位字符串(对于集合中存在的任何整数都是1;对于任何不存在的整数,则为0)。对于稀疏的大整数集,这在存储/内存方面将非常昂贵)。
出现在脑海中的另一种方法是对集合进行排序,并将键作为每个数字的数字表示的连接(由某个分隔符分隔)。因此,集合{2,1,3} -> "1/2/3“(使用"/”作为分隔符)和{30,1,2,4} => "1/2/4/30“
我想你也可以采用混合方法。所有元素< 63被编码成一个十六进制字符串,所有其他元素都被编码到一个字符串中。最后生成的键是: HEXxA/B/c .(使用"x“将小int十六进制字符串与集合中较大的int分隔开来)。
发布于 2015-03-10 05:49:24
如果没有更好的想法,希望这将有助于您的解决方案。
发布于 2015-03-10 05:55:54
我认为一个实际大小的键只能是一个哈希值--总是会有几对输入对相同的键进行散列,但是您可以使这种情况变得不太可能。
我认为排序然后应用标准哈希函数的想法是好的,但我不喜欢您的散列乘数。如果算术是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的传统。
https://stackoverflow.com/questions/28956827
复制相似问题