异或运算的性质与扩展
异或的性质
1. 0^N == N , N^N == 0
2. 异或运算满足交换律和结合率
3. 不用额外变量交换两个数:
//第一种
public static void process1() {
int N = 1000;
int a = 0;
for(int i = 0 ; i < N;i++) {
a = 2+5;
a = 4*7;
a = 6*8;
}
}
//第二种
public static void process2() {
int N = 1000;
int a = 0;
for(int i = 0 ; i < N;i++) {
a = 3 | 6;
a = 3 & 4;
a = 4 ^ 785;
}
}
//第三种
public static void main(String[] args) {
int a = 10;
int b = 10;
//不用额外变量交换两个数
a = a^b;
b = a^b;
a = a^b;
System.out.println(a);
System.out.println(b);
}
4. 一个数组中有一种数出现了奇数次,其他数都出现了偶数次,怎么找到这一个数:
//一个数组中有一种数出现了奇数次,其他数都出现了偶数次,怎么找到这一个数
public static void printOddTimesNum1(int[] arr) {
int eor = 0;
for (int cur : arr) {
eor ^= cur;
}
System.out.println(eor);
}
5. 一个数组中有两种数出现了奇数次,其他数都出现了偶数次,怎么找到这两个数:
//一个数组中有两种数出现了奇数次,其他数都出现了偶数次,怎么找到这两个数
public static void printOddTimesNum2(int[] arr) {
int eor = 0;
for (int i = 0 ; i < arr.length;i++) {
eor ^= arr[i];
}
// eor = a ^ b
// eor != 0
// eor必然有一个位置上是1
int rightOne = eor & (~eor + 1); // 提取出最右的1
int onlyOne = 0; // eor'
for (int cur : arr) {
if ((cur & rightOne) == 1) {
onlyOne ^= cur;
}
}
System.out.println(onlyOne + " " + (eor ^ onlyOne));
}
记录:2022年12月19日~