编程语言
首页 > 编程语言> > java – XOR如何真正起作用,它背后的魔力是什么?

java – XOR如何真正起作用,它背后的魔力是什么?

作者:互联网

问题可能是误导了一点,但我不知道如何以另一种方式提出问题.
hackerrank存在以下问题:

Consider an array of integers, where all but one of the integers
occur in pairs. In other words, every element in occurs exactly twice
except for one unique element.

Given the array find and print the unique element. [2,3,1,3,2] -> result is 1

enter image description here

我解决了这个问题:

private static int lonelyInteger(int[] a) {
        if(a==null)
            return 0;

         if(a.length<2)
             return a.length;

        Set<Integer> set = new HashSet<>();

        for(int i : a){

            if(set.contains(i)){
                set.remove(i);
            }else{
                set.add(i);
            }            
        }

        return (Integer) set.toArray()[0];
    }

然而,我们认为这个问题有一个简洁的解决方案:

private static int lonelyInteger(int[] a) {
         int b = a[0];

         for(int i = 1; i < a.length; i++){
             b ^= a[i];
         }
        return b;       
    }

问题是我不知道为什么工作?
我理解它是如何工作但不明白为什么它工作?
要理解我制作了一个小程序来输出每个步骤的结果:

public class BitwiseOperator {

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int[] a = new int[n];
        int sum = 0;
        in.nextLine();
        String line = in.nextLine();
        String[] numbers = line.split(" ");
        for (int i = 0; i < numbers.length; i++) {
            a[i] = Integer.valueOf(numbers[i]);
        }

        for (int i = 0; i < a.length; i++) {
            binary(sum, a[i]);
            sum ^= a[i];
            binary(sum);
            System.out.println();
            System.out.println();
            System.out.println();

        }
        System.out.println(sum);
    }


    private static void binary(int sum) {
        System.out.println(String.format("%16s", Integer.toBinaryString(sum)).replace(' ', '0') + " ->" + sum);
    }

    private static void binary(int sum, int i) {
        System.out.println(String.format("%16s", Integer.toBinaryString(sum)).replace(' ', '0') + " ->" + sum);
        System.out.println("XOR");
        System.out.println(String.format("%16s", Integer.toBinaryString(i)).replace(' ', '0') + " ->" + i);
        System.out.println("--------");
    }


}

如果输入以下输入:

2 3 2 1 3

输出是:

0000000000000000 ->0
XOR
0000000000000010 ->2
--------
0000000000000010 ->2



0000000000000010 ->2
XOR
0000000000000011 ->3
--------
0000000000000001 ->1



0000000000000001 ->1
XOR
0000000000000010 ->2
--------
0000000000000011 ->3



0000000000000011 ->3
XOR
0000000000000001 ->1
--------
0000000000000010 ->2



0000000000000010 ->2
XOR
0000000000000011 ->3
--------
0000000000000001 ->1



1

所以该程序实际上工作,但我真的需要了解为什么?

解决方法:

一个准确的证据,恕我直言,涉及群论(你可以建立基于xor的阿贝尔群):

> xor是一个群组操作
> 0是组0
> A是一个反向元素(因此任何A与自身相反).

当然我们必须证明(A xor B)xor C == A xor(B xor C)

由于A xor B == B x或A,我们有一个阿贝尔群,这就是为什么可以重新组合
任何顺序的项目:

  A XOR B XOR C XOR A XOR B ==
 (A XOR A) XOR (B XOR B) XOR C ==
  C

一般情况下:

   A xor B xor ... xor Z ==
  (A xor A) xor (B xor B) xor ... xor (distinct Item) ==
   0 xor 0 xor ... xor (distinct Item) ==
   distinct Item

标签:java,algorithm,bitwise-operators,binary
来源: https://codeday.me/bug/20190828/1752490.html