1.異或運算的基本性質:
兩個數的異或可以看做兩個數進行不進位的加法
(1).0^n = n, n ^ n = 0, 1^n = ~n
(2).滿足交換律:a^b = b^a 滿足結合律:(a^b)^c = a^(b^c)
(3).從(2)中可以推出,只要是同一批數進行異或,那么任意調換異或順序,不改變最終的結果
2.異或運算的實例運用:
(1).異或實現數據交換
使用前提:a,b不指向同一塊內存,否則a,b會全部置為0
1 private static void swap(int a,int b) { 2 a = a ^ b; 3 b = a ^ b; 4 a = a ^ b; 5 }
解析:設a=甲 b=乙
則第2行時候:a=甲^乙 b=乙
第3行時候:a=甲^乙 b=甲^乙^乙=甲^0=甲
第4行時候:a=甲^乙^甲=0^乙=乙 b=甲
(2).若一批數中,所有數據中只有一種數據出現了奇數次,其他均為偶數次,快速找出這個出現奇數次的數
直接將數組中所有數組進行異或即可得到該數
1 public static int FindOneOddTimes(int[] arr) 2 { 3 int ans = 0; 4 for (int i = 0 ;i <arr.length ;i++) 5 { 6 ans ^= arr[i]; 7 } 8 return ans; 9 }
若有兩種數據出現了奇數次,找到這兩個數:
設這兩個數分別為a和b
則得到的結果eor = a^b;因為a!=b,所有eor必定有一位為1,而這也意味着a和b在這一位上不想同
設該位為第i位,則此時,選擇異或所有第i位為1的數,所得的結果eor1就是a和b的某一個
再次選擇異或所有第i位為0的數,所得的結果eor2就是a和b的另外一個
1 public static void FindTwoOddTimes(int[] arr) 2 { 3 int ans1 = 0,ans2 = 0; 4 int eor = 0; 5 for (int i = 0; i < arr.length ; i++) 6 { 7 eor ^= arr[i]; 8 } 9 10 int rightOne = eor & (~eor + 1);//eor與eor的補碼相與即可獲得其最右位為1其余位均為0的值 11 //如:eor為101100100,則通過該行得到000000100 12 13 for (int i = 0 ; i < arr.length; i++) 14 { 15 if ((arr[i] & rightOne) != 0) 16 { 17 ans1 ^= arr[i]; 18 } 19 else 20 { 21 ans2 ^= arr[i]; 22 } 23 } 24 System.out.println(ans1 + " "+ ans2);