C++ 如何将三个整数组合成一个唯一的标记,使标记在C+中保持整数+;?
我尝试使用Cantor和Szuszik配对函数,但例如a=200,b=201,c=202C++ 如何将三个整数组合成一个唯一的标记,使标记在C+中保持整数+;?,c++,integer,unique,C++,Integer,Unique,我尝试使用Cantor和Szuszik配对函数,但例如a=200,b=201,c=202 结果P(a,b,c)=P(P(a,b),c)它已经是一个非常大的数字,不适合int 如果整数的顺序很重要(因此tag(a,b,c)!=tag(b,c,a)),您需要一个大小为N^3的标签,其中N是输入整数的最大值N^3-因为这是您可以生成的可能的三元组数(a、b、c)。每个都必须映射到唯一的值。因此,您需要您的标记能够保存N^3的值。映射可以按如下方式进行:a+b*N+c*N^2将[0:1000]范围内的三
结果P(a,b,c)=P(P(a,b),c)它已经是一个非常大的数字,不适合int 如果整数的顺序很重要(因此
tag(a,b,c)!=tag(b,c,a)
),您需要一个大小为N^3
的标签,其中N
是输入整数的最大值N^3
-因为这是您可以生成的可能的三元组数(a、b、c)
。每个都必须映射到唯一的值。因此,您需要您的标记能够保存N^3
的值。映射可以按如下方式进行:a+b*N+c*N^2
将[0:1000]范围内的三个数字唯一地组合在一起是没有问题的(假设系统上的int
为32位或更大):
此打包是安全的,因为1000小于210,因此这些数字将始终适合10位。如果所有整数的大小相同,则无法将三个整数唯一地适合一个整数。但是,您可以将三个较小的整数拟合为一个较大的整数。为了美观起见,我将修改您的问题,说您正试图将4个16位整数打包成1个64位整数(具有特定的要求使解决方案更加清晰)。您可以修改解决方案以满足您的需要:
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\u t a=61000,b=60000,c=48000,d=32000;
uint64_t e=0;
e=(a)输入整数有大小限制吗?不能将三个整数唯一地放入一个整数中。必须有一些标记重叠。我相信,三个数字可以在区间[0:1000]上唯一定义,即使它们是int。因此,将三个数字配对为[0:1000]这是我的问题好吧,那么没问题。写一个答案。卡尔·诺勒姆,正如我所说的,对于小数字,我们已经接受了极限:a=500,b=200,c=600P(Szuszik)=62851744106。而int的极限是214743647。P(a,b)=(a>=b?a*a+a+b:a+b*b)多么优雅、深思熟虑的答案!@2to1mux堆栈溢出可以使用更多像您这样的优秀绅士!干得好!您的意思是[0:1023]?OP询问1到1000之间的数字。请参阅问题的评论。
void unpack(int combined, int *a, int *b, int *c)
{
*a = combined >> 20;
*b = (combined >> 10) & 0x3ff;
*c = combined & 0x3ff;
}
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));
uint64_t a = 61000, b=60000, c=48000, d=32000;
uint64_t e = 0;
e = (a << 48) | (b << 32) | (c << 16) | d;