我正在寻找配对函数f:ZxZ - > Z,具有以下特点:
目前,我正在使用f(x,y)= x +(max(x)-min(x)+1)* y
它有效,我只是想知道是否可以有更高效地使用结果空间的另一个函数,考虑到:
我知道这意味着我无法映射所有x,y组合而不会导致溢出。 我很高兴能够确定转换是否适合64位。 因此,理想的映射函数将尽可能高效地使用可用的64位。
任何提示?
答案 0 :(得分:1)
CRC polynomials计算速度快,扩散速度快。我相信你会得到你最喜欢的语言库。 Concat都是128位的整数并计算CRC。
请记住,在没有冲突的情况下,不能以64位映射128位。
答案 1 :(得分:0)
要将两个64位整数编码为唯一的单个数字,可能会有2^64 * (2^64 -1)
个输入组合,因此,显而易见的Pigeonhole Principle,我们需要一个至少为2^64 * (2^64 -1)
的大小输出,等于2^128 - 2^64
,换句话说,你需要一个128位的容量来保存所有可能的输出。
我知道所有价值观都不存在。但这取决于值,而不是数据类型。例如。 f(4,5)仍然可以完成,即使4和5存储为64位整数。根据所使用的函数,很容易检查溢出(在这种情况下我不会使用映射)。
你知道的。也就是说,正如您所说,您可以为64位输入设置最大值上限。然后输出可以是64位有符号或无符号整数。
正在签署的输出,C#中的实现:
public static long GetHashCode(long a, long b)
{
if (a < int.MinValue || a > int.MaxValue || b < int.MinValue || b > int.MaxValue)
throw new ArgumentOutOfRangeException();
var A = (ulong)(a >= 0 ? 2 * a : -2 * a - 1);
var B = (ulong)(b >= 0 ? 2 * b : -2 * b - 1);
var C = (long)((A >= B ? A * A + A + B : A + B * B) / 2);
return a < 0 && b < 0 || a >= 0 && b >= 0 ? C : -C - 1;
}
输出是无符号的,是C#中的一个实现:
public static ulong GetHashCode(long a, long b)
{
if (a < int.MinValue || a > int.MaxValue || b < int.MinValue || b > int.MaxValue)
throw new ArgumentOutOfRangeException();
var A = (ulong)(a >= 0 ? 2 * a : -2 * a - 1);
var B = (ulong)(b >= 0 ? 2 * b : -2 * b - 1);
return A >= B ? A * A + A + B : A + B * B;
}
由于计算量较少,无符号实现会稍快一些。唯一配对的下限和上限是int.MaxValue
( - 2147483648)和int.MaxValue
(2147483647)。原始函数是taken from here。链接中提到的优雅配对功能是最节省空间的,因为它映射到可用空间中的每个点。有关类似方法的更多信息,请参阅Mapping two integers to one, in a unique and deterministic way