У меня есть четырехзначное число от 0000 до 1440. Я хочу сгенерировать эквивалентное четырехзначное число. Это означает, что я могу поменять число с эквивалентного числа. Основное требование — эквивалентное число должно полностью отличаться от исходного. Есть ли хорошее уравнение для этого?
Например, каждая цифра может быть заменена на 10 - digit
, Таким образом, 1440 становится 9660, а 1254 становится 9756.
Благодарю.
Вы можете использовать Линейный конгруэнтный Генератор с периодом 10000. Это генератор псевдослучайных чисел, который циклически перебирает каждое число в диапазоне 0-9999 один раз и только один раз. Чтобы сгенерировать свой номер, просто возьмите исходный номер и рассчитайте следующий номер в последовательности LCG.
LCG генерирует случайные числа по следующей формуле:
Иксп + 1 = ((XN * а) + в) мод м
Для генерации 4-значных чисел m должно быть 10000 (диапазон 0-9999).
Чтобы гарантировать отсутствие повторов («полный период»), вы должны выбрать значения для a и c, используя следующие критерии:
с и м относительно простые
а — 1 делится на все простые множители т
a — 1 кратно 4, если m кратно 4.
Первичные множители 10000 равны 2 и 5, и они также делятся на 4, поэтому любое кратное 20 + 1 будет работать как подходящее значение a. Для c просто выберите достаточно большое простое число.
например: m = 10000, a = 4781, c = 7621
Чтобы пойти другим путем, вам нужно сделать функцию обратимой. Увидеть этот ответ для объяснения математики за этим.
Вот простая реализация:
#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)
получает оригинал обратно.
Это, пожалуй, больше комментарий.
Я думаю, что ваш вопрос довольно расплывчатый, потому что вы не определяете «совершенно другое». Типичные «простые» способы это что-то вроде:
И, конечно, вы можете объединить их.
В вашем случае вы начинаете с диапазона 1441 и переходите к гораздо большему диапазону (10000). Это на самом деле дает вам больший диапазон возможных отображений.
Тем не менее, ключевым моментом является «чем отличается, то отличается»? Вы должны изменить свой вопрос, чтобы объяснить этот момент.