найти уникальный выход, основанный на двух входах? [дубликат]
На этот вопрос уже есть ответ здесь:
Мне нужно найти способ, такой, что пользователь должен ввести 2 числа (int) и для каждого другого значения один выход (int предпочтительно!) возвращенный.
Скажем, пользователь вводит 6, 8 он возвращает k, когда пользователь вводит что-либо еще подобно 6,7 или 9,8 или любому другому входу m, n, за исключением 6, 8 (даже если изменяется только один вход), получается совершенно другой выход. Но дело в том, что он должен быть уникален только для этого m, n, поэтому я не могу использовать что-то вроде m*n, потому что 6 X 4 = 24 но также, 12 X 2 = 24, поэтому выход не уникален, поэтому мне нужно найти способ, при котором для каждого другого входа есть совершенно другой выход, который не повторяется для любого другого значения.
EDIT: в ответ на Nicolas: диапазон ввода может быть что угодно, но будет меньше, чем 1000 (но больше, чем 1, конечно!)
EDIT 2 : в ответ на Rawling я могу использовать long (Int64) , но не предпочтительно использовать float или doulbe, потому что этот выход будет использоваться в цикле for, а float и double ужасны для цикла for, вы можете проверить это здесь
5 ответов:
Поскольку ваши два числа меньше 1000, вы можете сделать
k = (1000 * x1) + x2, чтобы получить уникальный ответ. Максимальное значение будет равно999999, что находится в пределах 32-битногоint.
Вы всегда можете вернуть a
long: из двух целых чиселaиb, return2^|INT_SIZE|*a + bЭто легко увидеть из принцип голубятни, что, учитывая два int, нельзя возвращать уникальный int для каждого другого входного сигнала. Пояснение: Если у вас есть 2 числа, каждое из которых содержит биты
n, то для каждого числа есть возможности2^n, и, следовательно, есть возможные пары(2^n)^2, поэтому из принципа piegeonhole-вам нужно, по крайней мере, битыlg_2((2^n)^2) = 2n, чтобы представить их,EDIT : ваш edit упоминает диапазон ваших чисел
[1,1000]- таким образом, можно применить ту же идею:1000*a + bсоздаст уникальный int для каждой пары. Обратите внимание, что по тем же причинам диапазон результирующего целого числа должен быть[1,1000000]- или вы получите столкновения.
Поскольку у меня нет 50 сообщений для комментариев, я должен сказать, что есть функции называютсяфункции сопряжения .
Функции спаривания, такие как функция спаривания Кантора(показанная на предыдущей ссылке) и функция спаривания Шудзика, которая позволяет входам быть бесконечными и все еще быть в состоянии обеспечить уникальный и детерминированный выход.
Вот еще один аналогичный вопрос о stackoverflow. (Отлично, мне нужно 10 репутации, чтобы разместить более двух ссылок..)
(http://) stackoverflow.com/questions/919612/mapping-two-integers-to-one-in-a-unique-and-deterministic-way
Правка: я опаздываю.
Если у вас нет жесткой верхней границы, вы можете сделать следующее:
Говоря математически, это вернет уникальное неотрицательное целое число для каждой (неотрицательной) пары целых чисел без верхней границы. Говоря программно, он столкнется с проблемами переполнения, которые можно преодолеть, используяint Unique (int x, int y) { int n = x + y; int t = (n%2==0) ? ((n/2) * (n+1)) : (n * ((n+1)/2)); return t + x; }longвместоintдля всего, кроме входных переменных.
Каноническое математическое решение состоит в использовании простых степеней. Поскольку каждое число можно разложить однозначно на его простые множители, возвращая
2^n * 3^m, вы получите различные результаты для каждого n и m.Это может быть расширено до
2^n * 3^m * 5^a * 7^b *11^cи так далее; вам нужно только проверить, что у вас не закончились 32-разрядные целые числа. Если есть риск переполнения, вы можете взять остаток после деления на простое число, большее, чем ваш входной диапазон, и у вас все равно будет уникальность.
Comments