異或操作的應用

1,異或運算的規則:

a) 0 xor 0 = 0

b) 0 xor 1 = 1

c) 1 xor 0 = 1

d) 1 xor 1 = 0


2, 異或運算的性質:

a)  a xor a = 0
b) (a xor b) xor c = a xor (b xor c)
c)  IF a xor b = c THEN a xor c = a xor (a xor b) = (a xor a) xor b = b


3, 異或的應用

Q1: 一個數組,除其中一個元素(如下面的99),其它的都是成對出現的,如何能快速找出那99的位置
……102,102,2,2,44,44,99,23,23,11,11 ……

請參考: 參考貼子

Answer 1:

把所有數組元素全部異或一下則得到非成對出現的元素99,然後順序查找99的位置。時間複雜度爲O(n)。

此解法較通用,適合如下兩種特殊情況:

a),如……102,102,2,2,2, 2,44,44,99,23,23,11,11 ……(連續但存在相同元素)

b),如...... 102,2,44,23,11,99,11,23,44,2,102......(配對但不連續)


若數據無素不會出現3(a)和(b)中情況,那麼可以採用一種更高效的算法:

Answer 2:

折半查找。

若數組a的元素個數爲(n+1),則n+1必爲奇數。數組a的序號爲0到n。

left = 0; right = n; m = (left+right)/2;

int find99(left,right);

m = (n+0)/2,

IF: m爲偶數,也即m兩邊的數量都爲偶數,分別判斷a[m]與a[m-1]、a[m+1]的值,若與a[m-1]相等,則99必在左側,那麼接下來就find99(left,m-1)。若與a[m+1]相等,則99必在右側,那麼find99(m+1,right)。若都不相等,則a[m] == 99,return m。
ELSE: 若m爲奇數,也即m兩邊的數量都爲奇數,分別判斷a[m]與a[m-1]、a[m+1]的值,若與a[m-1]相等,則99必在右側,find99(m+1,right)。若與a[m+1]相等,則99必在左側,find99(left,m-1)。若都不相等,則a[m] == 99,return m。


Q2:一個很大的數組,裏面有兩個數只出現過一次,其他數都出現過兩次,把這兩個數找出來

ref :參考貼子

Answer 1:

        在題目給出的很大的數組中,除要找的兩個不同的數字外,其它的數字都是成對出現的,根據上面說到的兩個相同的數字的異或其結果爲0。因此,如果將整個數組中的元素進行異或,所得到的結果應該是所求的那兩個不成對的數字的異或結果。

        假定數組中兩個不同的數字是95 ^ 99,則其異或的結果是0111100b,其中有4位是1,這表明這兩個數字的二進制表示中有4位是不同的。(從右往左數) 它們分別是第3、4、5、6這4位,於是我們只需要

       將數組中所有元素中第6位爲1的元素和0111100b異或,

or,將數組中所有元素中第5位爲1的元素和0111100b異或,

or,將數組中所有元素中第4位爲1的元素和0111100b異或,

or,將數組中所有元素中第3位爲1的元素和0111100b異或。

就可以得到所求之兩個數字中的一個數字。

        不妨以上面最後一條規則爲例來進行說明:數組元素中第3位爲1的數字,除所求的兩個數字之外,都是成對出現的,它們所產生異或的結果肯定是0。而所求的那兩個數字當中只有一個數字的第3位1。不妨假定這個數字是a(此時未知),另外一個要求的數字是b(此時未知)。很明顯,將a (此時未知)和0111100b異或就可以得到b (此時已知),再用0111100b和已經求出來的b (此時已知) 進行異或就可以得到a (此時已知)。比如上面的95的第3位爲1,所以用95 ^ 0111100b = 1011111b ^  0111100b = 1100011b = 99,再用99 ^ 0111100b = 1100011b ^ 0111100b = 1011111b = 95。

 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章