想象两个正整数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”
这种组合操作也应该是确定的(总是用相同的输入产生相同的结果),并且应该总是在整数的正侧或负侧产生一个整数。
当前回答
假设我们有两个数字B和C,把它们编码成一个数字A
A = b + c * n
在哪里
B= a % n = B
C= a / n = C
其他回答
下面是基于@nawfal给出的方法将@DoctorJ的代码扩展到无界整数。它可以编码和解码。它适用于普通数组和numpy数组。
#!/usr/bin/env python
from numbers import Integral
def tuple_to_int(tup):
""":Return: the unique non-negative integer encoding of a tuple of non-negative integers."""
if len(tup) == 0: # normally do if not tup, but doesn't work with np
raise ValueError('Cannot encode empty tuple')
if len(tup) == 1:
x = tup[0]
if not isinstance(x, Integral):
raise ValueError('Can only encode integers')
return x
elif len(tup) == 2:
# print("len=2")
x, y = tuple_to_int(tup[0:1]), tuple_to_int(tup[1:2]) # Just to validate x and y
X = 2 * x if x >= 0 else -2 * x - 1 # map x to positive integers
Y = 2 * y if y >= 0 else -2 * y - 1 # map y to positive integers
Z = (X * X + X + Y) if X >= Y else (X + Y * Y) # encode
# Map evens onto positives
if (x >= 0 and y >= 0):
return Z // 2
elif (x < 0 and y >= 0 and X >= Y):
return Z // 2
elif (x < 0 and y < 0 and X < Y):
return Z // 2
# Map odds onto negative
else:
return (-Z - 1) // 2
else:
return tuple_to_int((tuple_to_int(tup[:2]),) + tuple(tup[2:])) # ***speed up tuple(tup[2:])?***
def int_to_tuple(num, size=2):
""":Return: the unique tuple of length `size` that encodes to `num`."""
if not isinstance(num, Integral):
raise ValueError('Can only encode integers (got {})'.format(num))
if not isinstance(size, Integral) or size < 1:
raise ValueError('Tuple is the wrong size ({})'.format(size))
if size == 1:
return (num,)
elif size == 2:
# Mapping onto positive integers
Z = -2 * num - 1 if num < 0 else 2 * num
# Reversing Pairing
s = isqrt(Z)
if Z - s * s < s:
X, Y = Z - s * s, s
else:
X, Y = s, Z - s * s - s
# Undoing mappint to positive integers
x = (X + 1) // -2 if X % 2 else X // 2 # True if X not divisible by 2
y = (Y + 1) // -2 if Y % 2 else Y // 2 # True if Y not divisible by 2
return x, y
else:
x, y = int_to_tuple(num, 2)
return int_to_tuple(x, size - 1) + (y,)
def isqrt(n):
"""":Return: the largest integer x for which x * x does not exceed n."""
# Newton's method, via http://stackoverflow.com/a/15391420
x = n
y = (x + 1) // 2
while y < x:
x = y
y = (x + n // x) // 2
return x
再简单一点:给定两个数字,A和B让str为串联:'A' + ';' + 'B'。然后让输出为hash(str)。我知道这不是一个数学答案,但一个简单的python(有一个内置的哈希函数)脚本应该做这项工作。
我们可以在O(1)空间和O(N)时间内将两个数字编码为1。 假设您希望将0-9范围内的数字编码为1,例如。5和6。怎么做呢?简单,
5*10 + 6 = 56.
5 can be obtained by doing 56/10
6 can be obtained by doing 56%10.
即使是两位数的整数,比如56和45,56*100 + 45 = 5645。我们同样可以通过执行5645/100和5645%100来获得单个数字
但对于一个大小为n的数组,例如。A ={4,0,2,1,3},假设我们想对3和4进行编码,那么:
3 * 5 + 4 = 19 OR 3 + 5 * 4 = 23
3 :- 19 / 5 = 3 3 :- 23 % 5 = 3
4 :- 19 % 5 = 4 4 :- 23 / 5 = 4
通过推广,我们得到
x * n + y OR x + n * y
但我们还需要注意改变的值;所以结果是
(x%n)*n + y OR x + n*(y%n)
你可以通过除法和对结果取余来得到每个数字。
这可能吗? 两个整数的组合。它们都有- 2147,483,648到2147,483,647的范围,但你只会看到正数。 2147483647^2 = 4,61169e +18种组合。 因为每个组合都必须是唯一的,并且结果是一个整数,所以您需要某种神奇的整数来包含这个数量的数字。
还是我的逻辑有问题?
正整数的标准数学方法是利用质因数分解的唯一性。
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)