想象两个正整数A和b,我想把这两个组合成一个整数C。
不可能有其他整数D和E组合成C。 所以把它们和加法运算符结合是不行的。例:30 + 10 = 40 = 40 + 0 = 39 + 1 连接也不管用。例如“31”+“2”= 312 =“3”+“12”
这种组合操作也应该是确定的(总是用相同的输入产生相同的结果),并且应该总是在整数的正侧或负侧产生一个整数。
想象两个正整数A和b,我想把这两个组合成一个整数C。
不可能有其他整数D和E组合成C。 所以把它们和加法运算符结合是不行的。例:30 + 10 = 40 = 40 + 0 = 39 + 1 连接也不管用。例如“31”+“2”= 312 =“3”+“12”
这种组合操作也应该是确定的(总是用相同的输入产生相同的结果),并且应该总是在整数的正侧或负侧产生一个整数。
当前回答
看看这个:http://en.wikipedia.org/wiki/Pigeonhole_principle。如果A, B, C是同一类型,就不能做。如果A和B是16位整数,而C是32位整数,那么您可以简单地使用移位。
哈希算法的本质是它们不能为每个不同的输入提供唯一的哈希。
其他回答
正整数的标准数学方法是利用质因数分解的唯一性。
f( x, y ) -> 2^x * 3^y
缺点是,图像往往跨越相当大的整数范围,因此当涉及到在计算机算法中表示映射时,您可能会在为结果选择适当的类型时遇到问题。
你可以修改它来处理负x和负y,通过编码一个5和7次幂项的标志。
e.g.
f( x, y ) -> 2^|x| * 3^|y| * 5^(x<0) * 7^(y<0)
如果A和B可以用2个字节表示,那么可以用4个字节组合它们。把A放在最有效的一半,B放在最不有效的一半。
在C语言中,这给出了(假设sizeof(short)=2和sizeof(int)=4):
unsigned int combine(unsigned short A, unsigned short B)
{
return ((unsigned)A<<16) | (unsigned)B;
}
unsigned short getA(unsigned int C)
{
return C>>16;
}
unsigned short getB(unsigned int C)
{
return C & 0xFFFF; // or return (unsigned short)C;
}
使输入unsigned short或uint16_t确保他们在你|或+他们一起之前零扩展。否则- B会将上面的位设置为全1或,或者如果你添加,则从上半部分减去1。
强制转换(unsigned)A可以避免将窄类型默认提升为带符号int后左移的带符号溢出UB。对于更广泛的类型,也必须避免转移出位你保持,如((uint64_t)A << 32 | B,因为默认提升停止在int。
(unsigned)B强制转换是不必要的;重要的是它一开始是无符号空头B。左边的|是无符号的意味着它也将转换为无符号的。
你可以将它用于有符号类型,至少是getA和getB,你可以从combine返回有符号int,但是输入需要0 -extend,所以在C中你需要它们在扩大之前是无符号的short。比如((unsigned)(unsigned空头)A << 16) | (unsigned空头)B
你可能想要使用uint16_t和uint32_t,来定义类型宽度,以匹配你正在使用的移位计数。
看看这个:http://en.wikipedia.org/wiki/Pigeonhole_principle。如果A, B, C是同一类型,就不能做。如果A和B是16位整数,而C是32位整数,那么您可以简单地使用移位。
哈希算法的本质是它们不能为每个不同的输入提供唯一的哈希。
假设a是第一个,b是第二个。设p是a+1个质数,q是b+1个质数
然后,如果a<b,结果是pq,如果a>b,结果是2pq。如果a=b,让它是p^2。
构造一个映射并不难:
1 2 3 4 5 use this mapping if (a,b) != (b,a) 1 0 1 3 6 10 2 2 4 7 11 16 3 5 8 12 17 23 4 9 13 18 24 31 5 14 19 25 32 40 1 2 3 4 5 use this mapping if (a,b) == (b,a) (mirror) 1 0 1 2 4 6 2 1 3 5 7 10 3 2 5 8 11 14 4 4 8 11 15 19 5 6 10 14 19 24 0 1 -1 2 -2 use this if you need negative/positive 0 0 1 2 4 6 1 1 3 5 7 10 -1 2 5 8 11 14 2 4 8 11 15 19 -2 6 10 14 19 24
求任意a b的值有点难。