当在数组中找到缺失值时,无法理解`XOR`背后的逻辑

时间:2018-05-11 16:20:19

标签: java bit-manipulation xor

以下是我从here获得的代码示例。

public class Snippet {
    private static final int[] ARRAY = {1, 4, 3, 18, 2, 8, 9, 6, 5, 10,
            11, 12, 13, 14, 15, 16, 17, 19, 0, 20};

    //{1,2,4,5,6,8,7,9,3}
    private int getMissingElem() {
        int XOR = 0;
        for (int i = 0; i < 20; i++) {
            if (ARRAY[i] != 0) {
                XOR ^= ARRAY[i];
            }
            XOR ^= (i + 1);
        }
        return XOR;
    }

    public static void main(String[] args) {
        Snippet s = new Snippet();
        System.out.println(s.getMissingElem());
    }
}

我刚刚了解了XOR如何获得缺少数组元素的值。

1 个答案:

答案 0 :(得分:2)

XOR是按位。这意味着,给定两个整数值a, ba ^ b在该位置上有1位,当且仅当ab的位置为{时{1}},但不是两者。

值15将是按位(为简单起见,此处为8位)表示为1,而值60将按位表示为00001111。请注意,00111100将等于15 ^ 60,因为只有15位的位2-3等于00110011,而位6-7仅等于1

关于查找数组缺失元素的问题,只有当数组包含整数1到0时,它才有效,除了一个整数为0(前提条件)。

  • 请注意,XOR是可交换的和关联的。这意味着,ARRAY.lengtha ^ b == b ^ a
  • 适用于所有(a ^ b) ^ c == a ^ (b ^ c) == a ^ b ^ c)。此外,如果您对两次相同的数字进行异或,则会取消 out,结果变为0.给定任意数字a, b, cnn ^ n == 0
  • 对于所有a ^ n ^ n == aa,因为a ^ 0 == a的这一位是a,该位置中只有一位是1

基于XOR的解决方案背后的逻辑是,对于此数组中包含的所有数字,您在相同的数字上执行两次XOR,这将取消。唯一的例外是缺少的号码1,因为0 ^ n等于n

假设n是满足前提条件的数组:

  • 案例1:数字ARRAY出现在数组中。执行该异或的条件(*)是当循环位于m位置iARRAY[i] == m位置时。第一次满足条件时,我们有m - 1。随着循环的进行,再次满足相同的条件,因此我们得到XOR ^ m,其中XOR ^ m ^ k ^ m == XOR ^ (m ^ m) ^ k == XOR ^ k是对条件所在的第一个和第二个索引之间的数字进行异或运算的结果。

    < / LI>
  • 案例2:数组中缺少数字k。请注意,在迭代循环时,只满足前一个条件(*)一次。因此,我们有n

  • 因为XOR是可交换和关联的,所以我们最终得到XOR ^ n的最终结果。注意除了XOR == a^a^b^b^...^n...^x^x^y^y之外的所有数字在循环结束时都被异或两次,我们有n,因此我们根据需要获得了(a^a)^(b^b)^...^n^(x^x)^(y^y) == 0^0^...^n^...0^0