異或


1 基本概念

1.1 符號

異或是一種二進制的位運算,符號以 XOR 或 ^ 表示。

1.2 運算規則

相同為0,不同為1,即

1 ^ 1 = 0

0 ^ 0 = 0

1 ^ 0 = 1

由運算規則可知,任何二進制數與零異或,都會等於其本身,即 A ^ 0 = A。

1.3 異或性質

(1)交換律: A ^ B = B ^ A

(2)結合律: ( A ^ B ) ^ C = A ^ ( B ^ C )

(3)自反性: A ^ B ^ B = A (由結合律可推: A ^ B ^ B = A ^ ( B ^ B ) = A ^ 0 = A)

2.運用

2.1 變量交換

示例:將 a 和 b 兩個變量值交換,例如: a = 3,b = 7,交換后,a = 7,b = 3。

1 // 常規方法
2 int temp = a;  // temp = 3
3 a = b;         // a = 7
4 b = temp;      // b = 3
5  
6 // 異或方法
7 a = a ^ b;  // a = 3 ^ 7
8 b = a ^ b;  // b = (3 ^ 7) ^ 7 = 3 ^ (7 ^ 7) = 3
9 a = a ^ b;  // a = (3 ^ 7) ^ (3 ^ 7 ^ 7) = (3 ^ 3) ^ (7 ^ 7) ^ 7 = 7

2.2 排除偶次重復

示例:在一個整數數組中,僅存在一個不重復的數字,其余數字均出現兩次(或偶數次),找出不重復數字。

P1469 找筷子 - 洛谷 | 計算機科學教育新生態 (luogu.com.cn)

 1         int n;
 2     scanf("%d",&n);
 3     
 4     int ans=0;
 5     for(int i=1;i<=n;i++)
 6     {
 7         int x;
 8         scanf("%d",&x);
 9         ans^=x;
10     }
11     
12     printf("%d\n",ans);    

2.3 排除偶次重復變種

示例:將數字1-999存放在一個大小為1000的數組中,其中只有一個數字重復出現兩次,找出重復數字。

1000個整數依次異或運算,最終結果就是重復的數字,相當於重復數字與0進行異或,得到其本身。

1 int result = 0;
2 for (int index = 0; index < numArray.length; index++) {
3     result = result ^ numArray[index];
4 }
5 return result;

2.4 只出現一次的數字

題目:給定一個整數數組 nums,其中恰好有兩個元素只出現一次,其余所有元素均出現兩次。 找出只出現一次的那兩個元素。

思路:

(1) 先通過一次異或操作,重復元素會被抵消,最終結果相當於兩個單次出現的元素(分別記為one和two)的異或值;

(2) 由異或規則可知,若兩個元素one和two的異或值的某二進制位為1,則表示兩個元素在該二進制位上的值不同,即分別為1和0,找到其中一個滿足條件(為1)的二進制位(記為bitValue);

(3) 根據(2)找到的二進制位bitValue,可以將原數組分成兩個部分,one 和 two 分別在兩個部分,而相同的重復元素也會被分到同一個部分(因為其相應的二進制位的值是相同的);

(4) 對於兩個部分再次進行異或操作,即相當於 排除偶次重復 問題,最終可以得到兩個題解。

 1 class Solution {
 2  
 3   public int[] singleNumber(int[] nums) {
 4  
 5     // 通過異或操作,最終結果等於兩個單次出現的元素的異或值。
 6     int filterResult = 0;
 7     for (int num : nums) {
 8       filterResult ^= num;
 9     }
10  
11     // 計算首個為1(從右側開始)的二進制位的值
12     int bitValue = filterResult & (filterResult - 1) ^ filterResult;
13  
14     // 以首個為1的二進制位將原數組分為兩個部分並分別進行異或運算,最終結果為兩個題解。
15     int oneResult = 0, twoResult = 0;
16     for (int num : nums) {
17       if ((num & bitValue) > 0) {
18         oneResult ^= num;
19       } else {
20         twoResult ^= num;
21       }
22     }
23  
24     return new int[]{oneResult, twoResult};
25   }
26 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM