想象两个正整数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”
这种组合操作也应该是确定的(总是用相同的输入产生相同的结果),并且应该总是在整数的正侧或负侧产生一个整数。
当前回答
构造一个映射并不难:
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的值有点难。
其他回答
你正在寻找一个双射NxN - >n映射。这些是用于例如燕尾。请看这个PDF文件,它介绍了所谓的配对函数。维基百科介绍了一个特定的配对函数,即康托配对函数:
备注:三个
As others have made clear, if you plan to implement a pairing function, you may soon find you need arbitrarily large integers (bignums). If you don't want to make a distinction between the pairs (a, b) and (b, a), then sort a and b before applying the pairing function. Actually I lied. You are looking for a bijective ZxZ -> N mapping. Cantor's function only works on non-negative numbers. This is not a problem however, because it's easy to define a bijection f : Z -> N, like so: f(n) = n * 2 if n >= 0 f(n) = -n * 2 - 1 if n < 0
这可能吗? 两个整数的组合。它们都有- 2147,483,648到2147,483,647的范围,但你只会看到正数。 2147483647^2 = 4,61169e +18种组合。 因为每个组合都必须是唯一的,并且结果是一个整数,所以您需要某种神奇的整数来包含这个数量的数字。
还是我的逻辑有问题?
f(a, b) = s(a+b) + a,其中 s(n) = n*(n+1)/2
这是一个函数,它是确定的。 它也是单射的——f映射不同(a,b)对的不同值。你可以证明 它使用的事实是:s(a+b+1)-s(a+b) = a+b+1 <一个。 它返回非常小的值——如果你打算用它来做数组索引,那很好,因为数组不需要很大。 它是缓存友好的——如果两个(a, b)对彼此接近,那么f将彼此接近的数字映射到它们(与其他方法相比)。
我不明白您所说的:
应该总是产生一个整数 不管是积极的还是消极的 整数的边
我如何在这个论坛写(大于),(小于)字符?
再简单一点:给定两个数字,A和B让str为串联:'A' + ';' + 'B'。然后让输出为hash(str)。我知道这不是一个数学答案,但一个简单的python(有一个内置的哈希函数)脚本应该做这项工作。
尽管Stephan202的答案是唯一真正通用的答案,但对于有限范围内的整数,您可以做得更好。例如,如果你的范围是0..1万,那么你可以这样做:
#define RANGE_MIN 0
#define RANGE_MAX 10000
unsigned int merge(unsigned int x, unsigned int y)
{
return (x * (RANGE_MAX - RANGE_MIN + 1)) + y;
}
void split(unsigned int v, unsigned int &x, unsigned int &y)
{
x = RANGE_MIN + (v / (RANGE_MAX - RANGE_MIN + 1));
y = RANGE_MIN + (v % (RANGE_MAX - RANGE_MIN + 1));
}
结果可以适用于单个整数,其范围可达整数类型基数的平方根。这种打包方法比Stephan202更通用的方法效率稍高。它的解码也简单得多;对于初学者来说,不需要平方根:)