异或的魅力

  在认识异或之前,我们先来看一道经典题目,如何交换两个变量的数字?

//小bit,大梦想
public class Test{
    public static void main(String[] args) {
        int a = 10;
        int b = 20;
        System.out.println("交换前a = " + a);
        System.out.println("交换前b = " + b);
        int tmp = a;
        a = b;
        b = tmp;
        System.out.println("交换后a = " + a);
        System.out.println("交换后b = " + b);
    }
}

  大多数人应该都会选用上面的做法,创建一个新变量运转一下达到交换数字的目的。那如果不允许创建新变量呢?这时就要说起异或的魅力了。

  异或写作 ^ ,顾名思义,不一样的地方进行逻辑或运算,它的运算规则就是相同的的地方得0,不同的地方得1。例如:

int a = 10;     //10的二进制为  0000 1010
int b = 20;     //20的二进制为  0001 0100
int c = a ^ b;  //c的二进制为   0001 1110

  我们观察上面代码中的3个变量,不难发现,a ^ b可以得到c,同时a ^ c 能得到b,b ^ c能得到a。那么我们可以想象,是否可以不创建变量,只是将两个数字相互异或几次,从而达成交换数字的目的呢?

a = a ^ b;
b = a ^ b;
a = a ^ b;

  将a与b异或一次赋值给a,这时a就等于了一个“第三个数”;那么再将这个“第三个数”与b异或一次赋值给b,b就等于最初的a;最后用现在是“第三个数”的a与现在是最初的a的b异或一次,赋值给a,那a就等于了最初的b,这样就能达到一个交换数字的目的。理论成立,我们测试一下,看看结果如何:

public class Test{
    public static void main(String[] args) {
        int a = 10;
        int b = 20;
        System.out.println("交换前a = " + a);
        System.out.println("交换前b = " + b);
        a = a ^ b;
        //    0000 1010
        //    0001 0100
        //a = 0001 1110
        b = a ^ b;
        //    0001 1110
        //    0001 0100
        //b = 0000 1010
        a = a ^ b;
        //    0001 1110
        //    0000 1010
        //a = 0001 0100
        System.out.println("交换后a = " + a);
        System.out.println("交换后b = " + b);
    }
}

异或的魅力

果然,答案和我们预想的一样,你学废了吗?

上一篇:胡哥一分钟课堂第0001期 - Hybrid App(混合开发APP)


下一篇:关于HashMap的一些思考