数字操作数转换

时间:2015-08-04 01:29:49

标签: c++ algorithm math encoding digit

我在0000到1440之间有4位数字。我想生成一个等效的四位数字。这意味着我可以从同等数字中反转数字。基本要求是等效数字必须与原始数字完全不同。有一个很好的方程式吗? 例如,每个数字可以由10 - digit替换。因此,1440变为9660,而1254变为9756.

感谢。

2 个答案:

答案 0 :(得分:0)

这或许更像是评论。

我认为你的问题相当含糊,因为你没有定义完全不同的问题。典型的" easy"方式如下:

  • 反转号码。
  • 将数字替换为其他数字(一种简单的方法是将每个数字增加1)。
  • 替换其他对的数字对。

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

在你的情况下,你开始的范围是1,441并且映射到更大的范围(10,000)。这实际上为您提供了更大范围的可能映射。

然而,关键点是"差异有多大"?你应该修改你的问题来解释这一点。

答案 1 :(得分:0)

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

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

X n + 1 =((X n * a)+ c)mod m

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

为了保证不重复("完整期间"),您必须使用以下标准为a和c选择值:

  

c和m是相对素数

     

a - 1可被m

的所有素因子整除      如果m是4的倍数,则

a - 1是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)获得原始数据。