先舉乙個運用到異或的題目來深刻理解一下異或的內涵和在何種情況下應用其會使問題處理簡便:
1-1000放在含有1001個元素的陣列中,只有唯一的乙個元素值重複,其它均只出現
一次。每個陣列元素只能訪問一次,設計乙個演算法,將它找出來;不用輔助儲存空
間,能否設計乙個演算法實現? 解法
一、顯然已經有人提出了乙個比較精彩的解法,將所有數加起來,減去1+2+...+1000的和。
這個演算法已經足夠完美了,相信出題者的標準答案也就是這個演算法,唯一的問題是,如果數列過大,則可能會導致溢位。
解法二、異或就沒有這個問題,並且效能更好。
將所有的數全部異或,得到的結果與1^2^3^...^1000的結果進行異或,得到的結果就是重複數。
但是這個演算法雖然很簡單,但證明起來並不是一件容易的事情。這與異或運算的幾個特性有關係。
首先是異或運算滿足交換律、結合律。
所以,1^2^...^n^...^n^...^1000,無論這兩個n出現在什麼位置,都可以轉換成為1^2^...^1000^(n^n)的形式。
其次,對於任何數x,都有x^x=0,x^0=x。
所以1^2^...^n^...^n^...^1000 = 1^2^...^1000^(n^n)= 1^2^...^1000^0 = 1^2^...^1000(即序列中除了n的所有數的異或)。
令,1^2^...^1000(序列中不包含n)的結果為t
則1^2^...^1000(序列中包含n)的結果就是t^n。
t^(t^n)=n。
所以,將所有的數全部異或,得到的結果與1^2^3^...^1000的結果進行異或,得到的結果就是重複數。
當然有人會說,1+2+...+1000的結果有高斯定律可以快速計算,但實際上1^2^...^1000的結果也是有規律的,演算法比高斯定律還該簡單的多。
什麼是異或,簡單的說:
0^0=0
1^0=1
1^1=0
並且有a^0=a a^a=0
並且b^a^a=b 因為b^a^a=b^(a^a)=b^0=b
然後可以利用他來交換ab的值 只要這樣
a^=b
b^=a
a^=b
還有就是使用異或運算實現兩數交換:
通常我們實現兩數交換不得不引入乙個臨時變數temp作為媒介,而使用異或運算也能實現同樣的功能,甚至無需使用臨時變數。
這是乙個通常的做法:
int main()
關於異或(exclusive or)
wikipedia解釋
在數字邏輯中,邏輯算符互斥或閘(exclusive or)是對兩個運算元的一種邏輯分析型別,符號為xor或eor或⊕。與一般的或閘or不同,當兩兩數值相同為真..而有一數值不同時為否..
兩個運算元(命題):a與b的異或一般寫成a異或b,或者寫成
異或真值表ab
a^b000
0111
0111
0異或的小例子
假設a為二進位制數01,b為二進位制數10,a^b的結果為11並將其儲存在變數c中,經過反覆的測試,於是發現以下的規律:
11^01=10
11^10=01
c^a=b;
c^b=a;
可以很驚奇的發現,將兩數異或的結果與其中一數再進行異或,可以得到另乙個數。
原理很簡單,兩數異或的結果儲存了兩個數上每乙個二進位制位不同或相同的資訊,如果相應的二進位制位不同,就標誌為1,如果相同,則標誌為0。
由於任意乙個二進位制位與1異或有這樣乙個特性:
0^1=1
1^1=0
即與1異或後,都將自己轉換成相反的位
這樣,我們就使用異或運算交換了兩數
12(001100)
^ 34(100010)
-------------------
101110
101110 ^ 001100=100010
101100 ^ 100010=001100
int main()
result //
original result: a=12,b=34
transformed result: a=34,b=12
但是使用這種方法似乎與使用臨時變數沒有什麼區別?
其實不然,通過簡單分析可以發現臨時變數的值在整個過程中並沒有發生變化,因此也可以無需設定臨時變數。
a=a^b^a;
b=a^b^b;
於是可以使用第三種方法,將a設定為臨時變數
還可以寫得更簡潔一點:
a^=b^=a^=b;
異或以及一些小技巧
n n 0 0 n n n 2 n 2 n 2 n 2 說明 與 的區別 不帶符號位右移,即該數若為正數,則高位補0,若該數為負數,則高位補1 帶符號位右移,即不管該數為正數還是負數,高位都不0 1000 1 1100 0100 1 0010 1000 1 0100 0100 1 0010 將某乙個...
異或運算及其應用
異或是一種基於二進位制的位運算,用符號xor或者 表示,其運算法則是對運算子兩側數的每乙個二進位制位,同值取0,異值取1。它與布林運算的區別在於,當運算子兩側均為1時,布林運算的結果為1,異或運算的結果為0。交換律 a b b a 結合律 a b c a b c a b c d a b c 可以推出...
異或運算及其應用
異或是一種基於二進位制的位運算,用符號xor或者 表示,其運算法則是對運算子兩側數的每乙個二進位制位,同值取0,異值取1。它與布林運算的區別在於,當運算子兩側均為1時,布林運算的結果為1,異或運算的結果為0。交換律 a b b a 結合律 a b c a b c a b c d a b c 可以推出...