详解异或运算

什么是异或运算?

异或运算是位运算的一种,符号为:^
相同为0,不同为1。 容易与同或运算记混,根据异或的特性也叫 不进位相加。

异或运算的特质?

  1. N ^ 0 = N;
  2. N ^ N = 0;
  3. 异或运行满足交换律和结合律;

根据上面3个特质,个人觉得用无进位相加更便于理解了。


  • N ^ 0 = N
int a = 5;				//0101
int b = a ^ 0;			//0000
System.out.println(b);	//0101

位与位异或,相同为0,不相同为1,所以b的结果为5。
也就是N^0=N,任何数异或0都等于自己。


  • N ^ N = 0;
int a = 5;				//0101
int b = 5;				//0101
int c = a ^ b;			//0000
System.out.println(c);	

两个相同的数,二进制都是一样的,所以在位与位进行异或的时候都相同,每一位的结果都是0。
所以任何数与自己异或结果都等于0。


  • 交换律
int a = 5;
int b = 2;
int c = a ^ b;
int d = b ^ a;
System.out.println(c==b); //true

因为异或是位与位进行计算的,所以异或的顺序不重要,结果是一样的。

看一下下面的例子。

int a = 2;
int b = 4;
int c = 8;
int d = 7;
int e = a ^ b ^ c ^ d;
int f = a ^ c ^ d ^ b;

System.out.println(e == f); //true

这个例子说明了,abcd不管在什么位置,只要是异或在一起,任何位置都不影响结果。这就是异或满足交换律。
我再用二进制解释一下👇

a : 0010
b : 0100
c : 1000
d : 0111
------------
e : 1001

纵向观察,每一位进行相加,每一位的结果 不进位 ,结果就是1001。
也就是不进位相加。


  • 结合律
int a = 2;
int b = 5;
int c = 4;
int d = (a ^ b) ^ c;
int e = a ^ b ^ c;
int f = a ^ (b ^ c);
System.out.println(d == e);	//true
System.out.println(f == e);	//true

通过交换律得知,异或的顺序不会影响结果,所以在某一些数先异或,在异或另个数的时候,也不会影响结果。这就是异或满足结合律。

最最最简单的异或题

  • 如何不用额外变量交换两个数?
int a = 2;
int b = 5;

普通做法👇

int temp = a;
a = b;
b = temp;

这么做肯定是不对的,要求是不用额外的变量交换a、b的值。

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

为什么呢?
先不要把a看成2,也不要把b看成5。前面的N如果能看懂的话,在这里只需要把a看成a,把b看成b。
先看第一行的代码

a = a ^ b;

在看第二行代码

//此时的a = a ^ b
b = a ^ b;
//换言之
//b = a ^ b ^ b;

根据异或的交换律特性,先看b ^ b的部分,任何数异或自己都等于0。
这时 a ^ 0 不就等于a了吗。
再看第三行代码

//此时 
//b = a ^ b ^ b;
//a = a ^ b;
a = a ^ b;
//换言之
//a = a ^ b ^ a ^ b ^ b;

根据交换律,可以先看a ^ a = 0; b ^ b = 0;
这时 a = b ^ 0 ^ 0; 这句的结果应该不用解释了。

注意

上面这个解法只适用于a和b不在同一块区域,比如在一个数组中交换位置

int[] arr = new int[]{1,2,3,4};

如果交换a[1]与a[1]的位置,使用了上面的方法,最后a[1]的结果就会变成0。
需要特别注意!

总结

还有很多异或的算法,这道题不是入门,而是基础。
异或中还有很多其他的算法改「wo」日「zai」在「xue」唠「xue」!!
欢迎点赞评论交流!!
            在这里插入图片描述

  • 115
    点赞
  • 300
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 14
    评论
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

起个破名真费劲..

可赏可不赏,没脸要,哈哈

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值