3 回答
TA贡献1798条经验 获得超7个赞
2N
N
16
0 to 2^16 -1
2^16 * (2^16 -1)
2^16 * (2^16 -1)
2^32 - 2^16
32
Cantor配对函数:
(a + b) * (a + b + 1) / 2 + a; where a, b >= 0
两个最大的16位整数(65535,65535)的映射将是8589803520,正如您所看到的,这不能适合32位。
a >= b ? a * a + a + b : a + b * b; where a, b >= 0
现在(65535,65535)的映射将是4294967295,正如您所看到的,这是一个32位(0到2^32-1)整数。这就是这个解决方案理想的地方,它只是利用了空间中的每一个点,所以没有什么能获得更高的空间效率。
signed 16
-(2^15) to 2^15 -1
a
b
0 to 2^15 - 1
.
Cantor配对函数:
两个最大16位有符号整数(32767,32767)的映射将是2147418112,这只是缺少有符号32位整数的最大值。
(32767,32767)=>1073741823,小得多。
Cantor配对函数:
A = a >= 0 ? 2 * a : -2 * a - 1; B = b >= 0 ? 2 * b : -2 * b - 1; (A + B) * (A + B + 1) / 2 + A;
(-32768,-32768)=>8589803520,即64。16位输入的64位输出可能是不可原谅的!
Szudzik函数:
A = a >= 0 ? 2 * a : -2 * a - 1; B = b >= 0 ? 2 * b : -2 * b - 1; A >= B ? A * A + A + B : A + B * B;
(-32768,-32768)=>4294967295,对于无符号范围是32位,对于有符号范围是64位,但是更好。
A = a >= 0 ? 2 * a : -2 * a - 1; B = b >= 0 ? 2 * b : -2 * b - 1; C = (A >= B ? A * A + A + B : A + B * B) / 2; a < 0 && b < 0 || a >= 0 && b >= 0 ? C : -C - 1; (-32768, 32767) => -2147483648 (32767, -32768) => -2147450880 (0, 0) => 0 (32767, 32767) => 2147418112 (-32768, -32768) => 2147483647
2
-1
.
16
32
public static long PerfectlyHashThem(int a, int b) { var A = (ulong)(a >= 0 ? 2 * (long)a : -2 * (long)a - 1); var B = (ulong)(b >= 0 ? 2 * (long)b : -2 * (long)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; } public static int PerfectlyHashThem(short a, short b) { var A = (uint)(a >= 0 ? 2 * a : -2 * a - 1); var B = (uint)(b >= 0 ? 2 * b : -2 * b - 1); var C = (int)((A >= B ? A * A + A + B : A + B * B) / 2); return a < 0 && b < 0 || a >= 0 && b >= 0 ? C : -C - 1; }
2N
4N
2
2N
).
TA贡献2019条经验 获得超9个赞
int combine(short A, short B) { return A<<16 | B; } short getA(int C) { return C>>16; } short getB(int C) { return C & 0xFFFF; }
添加回答
举报