想象两个正整数A和b,我想把这两个组合成一个整数C。

不可能有其他整数D和E组合成C。 所以把它们和加法运算符结合是不行的。例:30 + 10 = 40 = 40 + 0 = 39 + 1 连接也不管用。例如“31”+“2”= 312 =“3”+“12”

这种组合操作也应该是确定的(总是用相同的输入产生相同的结果),并且应该总是在整数的正侧或负侧产生一个整数。


当前回答

这可能吗? 两个整数的组合。它们都有- 2147,483,648到2147,483,647的范围,但你只会看到正数。 2147483647^2 = 4,61169e +18种组合。 因为每个组合都必须是唯一的,并且结果是一个整数,所以您需要某种神奇的整数来包含这个数量的数字。

还是我的逻辑有问题?

其他回答

再简单一点:给定两个数字,A和B让str为串联:'A' + ';' + 'B'。然后让输出为hash(str)。我知道这不是一个数学答案,但一个简单的python(有一个内置的哈希函数)脚本应该做这项工作。

你的建议是不可能的。总会有碰撞。

为了将两个对象映射到另一个单独的集合,映射的集合必须具有预期组合数量的最小大小:

假设有一个32位整数,则有2147483647个正整数。选择其中两个顺序无关紧要且具有重复的组合,将得到2305843008139952128个组合。这并不适合32位整数的集合。

不过,你可以把这个映射压缩成61位。使用64位整数可能是最简单的。将高的字设置为较小的整数,低的字设置为较大的整数。

下面是基于@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是第二个。设p是a+1个质数,q是b+1个质数

然后,如果a<b,结果是pq,如果a>b,结果是2pq。如果a=b,让它是p^2。

尽管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更通用的方法效率稍高。它的解码也简单得多;对于初学者来说,不需要平方根:)