异或运算
问题
1、在数组当中有一群数,一种数出现了奇数次,其他数出现了偶数次,求这个出现了奇数次的数。
根据异或运算的3个性质可以得出: int eor = 0,eor异或数组当中每一个数,最后这个eor的值就是出现了奇数那个数。
//一个数组中有一种数出现了奇数次,其他数都出现了偶数次,怎么找到这一个数
public static void printOddTimesNum1(int[] arr) {
int eor = 0;
for (int cur : arr) {
eor ^= cur;
}
System.out.println(eor);
}
2、两种数出现了奇数次,其他数出现了偶数次,求这两种数。
还是设置这个eor这个数,最后eor= a ^ b a不等于b,说明a ^ b 不等于 0,证明a和b当中至少有一位上面是不同的 一个为0,一个1,假如就是第5位上面有不同的信息。所以我们在用一个变量eorx去异或第5位是1的那些数,我们就可以得到a或者b了。然后用eorx去异或eor,就可以得到例外一个数了。
public static void printOddTimeNum2(int[] arr){
int eor = 0;
for (int cur : arr) {
eor ^= cur;
}
/*
两个数出现了奇数次 那么结果一定是 a ^ b
且 a ^ b= eor 一定 不为0,因为两个数不相等
故a和b至少有一位不相等
故我们可以按照这一位来将这个数组分为两个区域
*/
// 取出最右边的1
int eorRight = eor & ( ~eor + 1);
System.out.println("最左边的1:" + eorRight);
int eor1 = 0;
for(int cur: arr){
//按照这一位来进行划分 这里的条件可以为1也可以为0
if((cur & eorRight) == 0 ){
eor1 ^= cur;
}
}
System.out.println(eor1);
//算出来一个数,那么例外一个数也出来了。
int a = eor ^ eor1;
System.out.println(a);
}