无进位相加
0 ^ N = N;
N ^ N = 0;
偶数个相同的数,异或的 结果为 0 , 奇数个相同的数,异或结果为1。 交换律 结合律
a 和 b 的值发生交换
a = a ^ b;
b = a ^ b;
a = a ^ b;
注意 a 和 b 在内存中的位置不一样。
一个数组中有一种数出现了奇数次,其他数都出现了偶数次,怎么找到这一个数
// arr中,只有一种数,出现奇数次
public static void printOddTimesNum1(int[] arr) {
int eO = 0;
for (int cur : arr) {
eO ^= cur;
}
System.out.println(eO);
}
一个数组中有两种数出现了奇数次,其他数都出现了偶数次,怎么找到这两个数
假设是 a,b
eor != 0
// arr中,有两种数,出现奇数次
public static void printOddTimesNum2(int[] arr) {
int eO = 0, eOhasOne = 0;
for (int curNum : arr) {
eO ^= curNum;
}
int rightOne = eO & (~eO + 1);//e0 & (-e0) 提取一个数的最右侧的1
for (int cur : arr) {
if ((cur & rightOne) != 0) {
eOhasOne ^= cur;
}
}
System.out.println(eOhasOne + " " + (eO ^ eOhasOne));
}
测试方法
public static void main(String[] args) {
int a = 5;
int b = 7;
a = a ^ b;
b = a ^ b;
a = a ^ b;
System.out.println(a);
System.out.println(b);
int[] arr1 = { 3, 3, 2, 3, 1, 1, 1, 3, 1, 1, 1 };
printOddTimesNum1(arr1);
int[] arr2 = { 4, 3, 4, 2, 2, 2, 4, 1, 1, 1, 3, 3, 1, 1, 1, 4, 2, 2 };
printOddTimesNum2(arr2);
}
提取一个数(N)的最右侧的1
int rightOne = eO & (~eO + 1);//e0 & (-e0) 提取一个数的最右侧的1