异或技巧

SyEic_L MVP++

交换

交换int a 和 int b的位置

1
2
3
4
5
6
int a = 10;
int b = 20;

a = a ^ b;
b = a ^ b; //b = a ^ b ^ b = a
a = a ^ b; //a = a ^ b ^ b(a) = b

a和b不能是同一个数(内存意义上),否则结果会是0

数组查找一个有奇数个的数字(其余全偶数个)

  • ^具有交换律:a ^ b = b ^ a
  • 偶数个某数异或等于0:a ^ a ^ a ^ a = 0
  • 奇数个某数异或等于本身:b ^ b ^ b = b
1
2
3
4
5
6
7
8
void printOddTimesNum1(int[] arr){
int eor = 0;
for (int i = 0; i < arr.length(); i++){
eor = eor ^ arr[i];
}
cout << eor << endl;
return ;
}
  • 时间复杂度:O(n)O(n)
  • 空间复杂度:O(1)O(1)

查找两个有奇数个的数字

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void printOddTimesNum2(int[] arr){	//arr中有奇数个a和奇数个b
int eor = 0;
for (int i = 0; i < arr.length(); i++){
eor = eor ^ arr[i]; //eor = a ^ b
}
int rightOne = eor & (~eor + 1); //eor中最右侧一位1,即a和b不同的一位1
int eor2 = 0;
for (int i = 0; i < arr.length(); i++){
if ((arr[i] & rightOne == 0)){
eor2 = eor2 ^ arr[i];
}
}
int a = eor2;
int b = eor2 ^ eor; //a ^ (a ^ b)
cout << a << " " << b << endl;
return ;
}
  • 其中int rightOne = eor & (~eor + 1);的原理:
    • 假设a = 1101110010
      b = 0010101010
    • eor = 1111011000
    • ~eor = 0000100111
    • ~eor + 1 = 0000101000
    • eor & (~eor + 1) = 0000001000
  • Title: 异或技巧
  • Author: SyEic_L
  • Created at : 2025-09-19 18:52:04
  • Updated at : 2025-09-19 18:52:04
  • Link: https://blog.syeicl.vip/2025/09/19/异或技巧/
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments