Почему этот элегантный метод сопряжения java не дает правильного результата?

#java #algorithm #function #math

#java #алгоритм #функция #математика

Вопрос:

Я соединяю два числа, чтобы сформировать уникальный номер, используя элегантное сопряжение. Но когда я соединяю два одинаковых числа, например, «пара (12,12)», это дает мне 156. Когда я хочу его распаковать, он даст мне (0,12). Затем я попытался выполнить сопряжение (0,12), это также дает мне 156. Все остальные числа дают уникальный номер, я могу соединять и разъединять их, если я не соединяю одно и то же число; (10,10), (9,9) и т.д.

Где я ошибся, пожалуйста?

 public class elegantPairing {

    /**
    * @param x
    * @param y
    * @return 
    */
   public static int pair(int x, int y) {
    return x > y ? x * x   x   y : y * y   x;
   }

   public static int[] unpair(int z) {
       int b = (int) Math.sqrt(z);
       int a = z - b * b;
       return a < b ? new int[]{a, b} : new int[]{b, a - b};
   }
   public static void main(String[] args) throws IOException {
    int firstValue = unpair(110)[0];
        int secondValue = unpair(110)[1];
        int paired=pair(10,10);
        System.out.println(firstValue "     " secondValue "     Paired       " paired);
   }

}
 

Комментарии:

1. Должно ли это условие быть x >= y ?... ?

2. Ты, мой друг, спасатель жизни, думал об этом более 40 минут. Сделайте это ответом.

3. Я бы предпочел не делать этого, поскольку это был удар в темноте, основанный на том, что вы говорите, что он не работает с равными аргументами. Я, честно говоря, не понимаю, что должен делать этот код, и мне не нравится отвечать, если я не могу объяснить свой ответ. Если вы можете объяснить, почему это изменение исправило его, вполне приемлемо ответить на ваш собственный вопрос.

Ответ №1:

Carcigenicate прав.

Для функции pair она берет наибольшее из двух чисел (скажем, a) и выдает число, которое больше, чем (a) в квадрате, и меньше, чем (a 1) в квадрате, используя одну из двух формул: либо (1) z = a * a a b, либо (2) z = a * a b, где b — меньшее число x и y.

Вы можете проверить, что любая формула дает число z, которое больше, чем (a) в квадрате, и меньше, чем (a 1) в квадрате.

Поэтому, когда вы распаковываете, извлечение квадратного корня из z всегда дает a, большее из двух исходных чисел.

Предположим, что x> y. Тогда большее из исходных чисел было x, поэтому a = x и b = y, а a> b . Затем мы использовали формулу 1,

 z = a * a   a   y
 

и

 y = z - (a * a) - a
 

и у нас (x, y) равно (a, z — (a * a) — a)
Эта формула является функцией распаковки для x> y и a> b.

Предположим, что x < y. Тогда большее из исходных чисел было y, поэтому a = y, а b = x и b < a . Затем мы используем формулу 2,

 z = a * a   x
 

и

 x = z - (a * a)
 

и у нас (x, y) равно (b, z — (a * a))
Эта формула является функцией распаковки для x < y и a > b, за исключением переменных a и b, переключаемых в функции распаковки.

А как насчет того, когда x = y? В соответствии с функцией распаковки используется более сложная формула распаковки, соответствующая x> y и a> b.

Таким образом, исходная формула для x> y одинакова для x = y в соответствии с функцией распаковки. Что означает, что исходная функция сопряжения должна быть: x> = y? x * x x y : y * y x;