2

我尝试使用 Cantor 和 Szuszik 配对函数,但例如 a = 200, b=201 c=202 结果 P(a, b, c) = P(P(a,b),c) 它已经非常大了不适合int的数字。

4

3 回答 3

10

唯一地组合 [0:1000] 范围内的三个数字是没有问题的(假设int在您的系统上是 32 位或更大,即):

int combine(int a, int b, int c)
{
    return (a << 20) | (b << 10) | c;
}

稍后提取它们:

void unpack(int combined, int *a, int *b, int *c)
{
    *a = combined >> 20;
    *b = (combined >> 10) & 0x3ff;
    *c = combined & 0x3ff;
}

这种打包是安全的,因为 1000 小于 2 10,所以这些数字总是适合 10 位。

于 2013-05-22T17:17:06.697 回答
2

如果所有整数的大小相同,则不能将三个整数唯一地放入一个整数中。但是,您可以将三个较小的整数放入一个较大的整数中。为了优雅起见,我将修改您的问题,说您正在尝试将 4 个 16 位整数打包成 1 个 64 位 int (具有特定要求使解决方案更加清晰)。您可以修改解决方案以满足您的需求:

uint16_t a = 61000, b=60000, c=48000, d=32000;
uint64_t e = 0;

memcpy((char*)&e, &a, sizeof(a));
memcpy((char*)&e + (1*sizeof(b)), &b, sizeof(b));
memcpy((char*)&e + (2*sizeof(c)), &c, sizeof(c));
memcpy((char*)&e + (3*sizeof(d)), &d, sizeof(d));  

编辑:这是一个使用按位运算符和位移的更简洁的版本(它假设每个被打包的整数只使用最低有效的 16 位)

uint64_t a = 61000, b=60000, c=48000, d=32000;
uint64_t e = 0;

e = (a << 48) | (b << 32) | (c << 16) | d;
于 2013-05-22T17:17:26.180 回答
1

如果整数的顺序很重要(所以tag(a,b,c) != tag(b,c,a)),您需要一个大小标签,N^3其中N输入整数的最大值。N^3- 因为这是(a,b,c)你可以做出的可能的三倍数。每个都必须映射到唯一的值。所以你需要你的标签能够保持N^3. 映射可以如下完成:a + b * N + c * N^2

于 2013-05-22T17:15:32.433 回答