咱们一般把异或定义为不一样为1,相同为0,即如以下真值表所显示:java
a | b | a ^ b |
---|---|---|
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 0 |
但从另一方面想,咱们能够将异或运算认为是二进制的无进位相加:数组
设 a = 10110101学习
b = 01011101code
则 a ^ b = 11101000内存
至关于每位各自相加可是没有进位。table
int a = 甲; //假设a的值为甲,b的值为乙 int b = 乙; /*下面的程序用于交换两个数的值*/ a = a ^ b; b = a ^ b; a = a ^ b;
就这样,a和b的值就已经进行了交换,是否是有点难以想象!😄class
下面咱们来具体分析一下三步运算中a和b的值:变量
a = a ^ b; //a = 甲 ^ 乙 b = 乙 b = a ^ b; //a = 甲 ^ 乙 b = 乙 ^ 甲 ^ 乙 = 甲 ^ (乙 ^ 乙) = 甲 a = a ^ b; //a = 甲 ^ 乙 ^ 甲 = (甲 ^ 甲) ^ 乙 = 乙 b = 甲
是否是清楚了不少呢?有没有以为这种方法很神奇?😁二进制
但这种方法也有必定的限制😢,==使用时必定要注意这两个变量是否指向一个内存地址!!!==(应用到数组中就是数组下标是否相同),若是两个变量指向一个内存地址,那么异或操做会将变量的值置为0。程序
- 一个数组中,一种数出现了奇数次,其余数出现了偶数次,如何找出这个出现奇数次的数?
分析:通过上面的分析,很容易就想到了用异或的方法,由于只有一个奇数次数,其它都是偶数次数,若是将数组中全部数进行异或操做,那么最后剩下的那个数即是咱们所求的奇数次数。
解决:定义一个初值为0的变量,分别与数组中的每一个数异或,最后这个变量中保存的值就是所求的奇数次数。
- 一个数组中,两种数出现奇数次,其余数出现偶数次,如何求出这两个出现奇数次的数?
分析:😶这下有两个奇数次数了,该怎么办呢?不慌,让咱们看看这组数异或后的结果是什么。
显然,这组数异或最后就剩这两个奇数次数了。设这两个数分别为a和b。则异或的最后结果为a ^ b。由于是两种数,因此a != b,则a ^ b != 0,即a和b至少有一个位上是不一样的,a ^ b至少在某一位上为1,由a ^ b的结果能够求得这个位。将该数组分红两种,一种是该位上为1的,另外一种是该位上不为1的,则a和b分别位于两种数组中。取一个eor'
,令其该位置为1其余位置为0,用eor'
异或数组中全部该位上为1的数,则最后结果必定为a或b。再将a或b与以前所求的a ^ b在进行异或操做,就能够求出另一个数。至此,a和b都已求出。
有没有以为异或运算很神奇呢?😁
本人系菜鸟一枚,所写文章皆为学习总结,大佬请轻喷😱 谢谢阅读😘,欢迎补充!