我在0000到1440之间有4位数字。我想生成一个等效的四位数字。这意味着我可以从同等数字中反转数字。基本要求是等效数字必须与原始数字完全不同。有一个很好的方程式吗?
例如,每个数字可以由10 - digit
替换。因此,1440变为9660,而1254变为9756.
感谢。
答案 0 :(得分:0)
这或许更像是评论。
我认为你的问题相当含糊,因为你没有定义完全不同的问题。典型的" easy"方式如下:
而且,您当然可以将这些结合起来。
在你的情况下,你开始的范围是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)
获得原始数据。