数字操作数字转换

Digit manipulation number conversion

我有从 0000 到 1440 的 4 位数字。我想生成一个等效的四位数字。这意味着我可以将数字与等效数字相反。基本要求是等效数字必须与原始数字完全不同。有没有一个好的方程式可以做到这一点? 例如,每个数字都可以用 10 - digit 代替。这样,1440就变成了9660,1254就变成了9756。

谢谢。

这也许更像是一条评论。

我觉得你的问题比较含糊,因为你没有定义"completely different"。典型的 "easy" 方式类似于:

  • 反转数字。
  • 用这些数字替换其他数字(一种简单的方法是将每个数字递增 1)。
  • 用数字对替换其他数字对。

而且,您当然可以将这些结合起来。

在您的例子中,您从 1,441 的范围开始并映射到更大的范围 (10,000)。这实际上为您提供了更大范围的可能映射。

不过,重点是"how different is different"?你应该修改你的问题来解释这一点。

您可以使用周期为 10000 的 Linear Congruential 生成器。这是一个伪随机数生成器,它循环遍历 0-9999 范围内的每个数字一次且仅一次。要生成您的号码,只需取原始号码并计算 LCG 序列中的下一个号码。

LCG 使用以下公式生成随机数:

Xn+1 = ((Xn * a) + c) mod m

要生成 4 位数字,m 应为 10000(范围为 0-9999)。

为了保证不重复(“完整周期”),您必须使用以下标准 select a 和 c 的值:

c and m are relatively prime

a - 1 is divisible by all prime factors of m

a - 1 is a multiple of 4 if m is a multiple of 4.

10000的质因数是2和5,而且还能被4整除,所以20+1的任意倍数都可以作为a的合适值。对于 c 只需选择一个相当大的素数。

例如:m = 10000,a = 4781,c = 7621

要反其道而行之,您需要使函数可逆。请参阅 this answer 了解其背后的数学解释。

这是一个简单的实现:

#define M (10000)
#define A (4781)
#define C (7621)

int extendedEuclidY(int a, int b);

int extendedEuclidX(int a, int b)
{
    return (b==0) ? 1 : extendedEuclidY(b, a-b*(a/b));
}

int extendedEuclidY(int a, int b)
{
    return (b==0) ? 0 : extendedEuclidX(b, a-b*(a/b)) - (a/b) * extendedEuclidY(b, a-b*(a/b));
}

int forward(int x)
{
   return ((x*A)+C)%M;
}

int backward(int x)
{
   return ((extendedEuclidX(A, M)*(x-C)%M)+M)%M;
}

int main()
{
    int x;
    for(x=0; x<1440; x++)
    {
        printf("%d <-> %d\n", backward(forward(x)), forward(x));
    }
    
    return 0;
}

我已经从链接的答案中改编了 extendedEuclid 函数。

forward(x) 找到你的对等号码,backward(x) 找回原来的号码。