下面的內容均來自於網路的收集和彙總。
異或的實質是按位模2加,簡單理解就是不進製加法如:
1⊕1 = 1^1 =0;
1⊕0 = 1^0 =1;
0⊕0 = 0^0 =0;
按位模2加:
101 ^ 110 ^ 111 = 100
101
110111
--------
322%2
--------
100
交換律:a ^ b = b ^ a;
結合律:a ^ b ^ c = (a ^ b) ^ c =a ^ (b ^ c);
恒等律:a ^ 0 = a;
歸零律:a ^ a = 0;
自反性:a ^ b ^ b = a ^ 0 = a;
對於任意的 x: x ^ (-1) = ~x;
如果 a ^ b = c ,那麼 a ^ b = c,b ^ c = a;
a ^ b = (!a) ^ (!b)
(!a) ^ b = a ^ (!b) = !( a ^ b )
看看第6條(為簡單化,按8位計算):
關鍵是-1的二進位製碼是多少?
1的二進位製碼為00000001, -1 + 1 =0 ,所以可以推出 -1 的二進位製碼為:11111111
00000001 + 11111111 = 00000000, 最高位被溢位。
那麼 x ^ (-1) = x ^ (11111111) = ~x;
變數交換判斷兩個數是否相等排除偶次重複(奇偶性判斷)格雷碼(gray code)錯誤檢測-crc校驗錯誤檢測-奇偶校驗資訊加密偽隨機數產生雙向鍊錶連續交替訊號產生
1.變數交換
真的不太好理解,慎用。
int a = 0x01;
int b = 0x10;
a = a ^ b;
b = a ^ b;
a = a ^ b;
2.判斷兩個數是否相等如果兩個數相等,異或結果為0, 不等為1, 為啥不直接用 == 呢?
3. 排除偶次重複(奇偶性判斷)
由a ^ a = 0, 得a ^ b ^ b = a ^ 0 = a; 偶數次重複的數都會被異或成0
4.格雷碼(gray code)
在通訊上用的一種編碼方式,編碼的過程當中主要用到了異或。
5.錯誤檢測-crc校驗
看了很多,下面這個博主講得算是比較易懂的
6.錯誤檢測-奇偶校驗
就是檢測傳輸資料中二進位制位為1的個數的奇偶性,就是對傳輸的資料按位進行異或, 1的個數為奇數,奇偶檢驗為1, 當1的個數為偶數時,奇偶校驗位0,
還有一種變種,較lrc,(longitudinal redundancy check), 這種是按位元組(8位)進行異或,原理差不多。
7.資訊加密
由異或的性質:a ^ b ^ b = a ^ 0 = a; 假設要傳輸的資訊為a, 並約定傳送方和接收方的共同秘鑰為b,
在傳送方,用秘鑰對資訊進行異或之後再進行傳送, 即傳送的資料為: a ^ b;
在接收方,收到的資料為 a ^ b, 那麼用秘鑰再進行一次異或, a ^ b ^ b = a , 就可以還原出原始資訊資料。
沒有秘鑰的人拿到的資料是亂碼。
8.偽隨機數產生
對最高的兩位數進行異或,然後左移一位,並把異或的結果放到第0位,最開始需要乙個種子數,這種方法產生出來的數列是沒有什麼規律的,看起來像是隨機數。
9.雙向鍊錶
看下面這個鏈結
10.連續交替訊號產生
int x = 0x01;
int y = 0x10;
for (int n = x; true; n ^= (x ^ y))
std::cout << n << " ";
1-1000放在含有1001個元素的陣列中,只有唯一的乙個元素值重複,其它均只出現
一次。每個陣列元素只能訪問一次,設計乙個演算法,將它找出來;不用輔助儲存空
間,能否設計乙個演算法實現?
解法一、將所有數加起來,減去1+2+...+1000的和。只是如果數列過大,則可能會導致溢位。
解法二、異或,將所有的數全部異或,得到的結果與1^2^3^...^1000的結果進行異或,得到的結果就是重複數。
乙個陣列存放若干整數,乙個數出現奇數次,其餘數均出現偶數次,找出這個出現奇數次的數?
解法同上
題目:給定乙個整數陣列 ,其中恰好有兩個元素只出現一次,其餘所有元素均出現兩次。 找出只出現一次的那兩個元素。
(1) 全部元素先通過一次異或操作,重複元素會被抵消,最後結果是兩個單次出現的元素的異或值;
(2) 第1步最後的結果是兩個不同元素的異或值,其必定存在某乙個二進位制位不為0, 打個比方第1步異或的結果為0x06, 也就是0000 0110, 其第1,和第2位不為0, 那麼我們可以取0x04 或者 0x02做為比較值,我們可以叫他 bitvalue
(3) 根據(2)找到的二進位制位bitvalue,可以將原陣列分成兩個部分(a部分和b部分),a部分必定包含其中乙個不同的元素,而另乙個不同元素必定在另一部分b。
(4) 對於兩個部分a,b分別再次進行異或操作,即相當於 排除偶次重複 問題,最終可以得到兩個題解。
int main()
; int sum = 0;
for (int i = 0; i < t1.size(); i++)
int tmp = 0;
while (sum > 0)
tmp++;
sum = sum / 2;
} int bitvalue = 0x01 << tmp;
int one = 0, two = 0;
for (int i = 0; i < t1.size(); i++)
else
two ^= t1[i];
} std::cout << one << " " << two << std::endl;
std::cin.get();
return 0;
}
按位模3加
題目:給定乙個整數陣列 ,其中乙個元素只出現一次,其餘所有元素均出現三次。 找出只出現一次的那個元素。
解法:參考異或的操作,異或的操作可以排除掉偶數次的元素,異或的操作實質是什麼呢?其實就是開篇所說的按位模2加,
那麼我們可以推理出按位模3加,可以排除出現3次,6次,9次。。。等的的元素。
如 陣列 為
9 1001
9 1001
9 1001
5 0101
7 0111
7 0111
7 0111 +
--------------
3437
%3--------------
5 0101
關於異或(XOR)的有趣應用
異或是個非常有意思的東西,利用異或的性質我們可以做一些有意思的事情。異或加密解密 下面是乙個非常簡單的加密解密函式 public static string encryption string srcstring,char key return new string srcchars 給出測試 st...
異或運算的性質
異或是一種基於二進位制的位運算,用符號xor或者 表示,其運算法則是對運算子兩側數的每乙個二進位制位,同值取0,異值取1。它與布林運算的區別在於,當運算子兩側均為1時,布林運算的結果為1,異或運算的結果為0。簡單理解就是不進製加法,如1 1 0,0 0 0,1 0 1。性質 1 交換律a b a b...
異或的性質和運算
異或是一種基於二進位制的位運算,用符號xor或者 表示,其運算法則是對運算子兩側數的每乙個二進位制位,同值取0,異值取1。它與布林運算的區別在於,當運算子兩側均為1時,布林運算的結果為1,異或運算的結果為0。簡單理解就是不進製加法,如1 1 0,0 0 0,1 0 1。性質1 交換律 2 結合律 3...