算法 -- 異或運算符

 

參考:http://longcxm.iteye.com/blog/1461543html

   http://www.41443.com/HTML/Java/20150131/309079.htmljava

   http://www.cnblogs.com/suoloveyou/archive/2012/04/25/2470292.html面試

在java程序裏面的異或用法: 

相同輸出0,不一樣輸出1,例如: 
System.out.println(1^1); 輸出0 
System.out.println(1^2);輸出3,由於最後2個低位都不同,全部輸出3 

    異域的概念是相同爲0不一樣爲1.若是兩個數值異或後的值相同,異或前可能不一樣。 
好比二進制:0010^0001=0011 而0000^0011=0011。 異或要慎用。 


    已到有意思的題目:不少成對出現數字保存在磁盤文件中,注意成對的數字不必定是相鄰的,如2, 3, 4, 3, 4, 2……,因爲意外有一個數字消失了,如何儘快的找到是哪一個數字消失了? 

   因爲有一個數字消失了,那一定有一個數只出現一次並且其它數字都出現了偶數次。用搜索來作就不必了,利用異或運算的兩個特性——1.本身與本身異或結果爲0,2.異或知足 
交換律。 

public static int findLost(int a[]){ 
        int result=0; 
        for(int i=0;i<a.length;i++) { 
            result^=a[i]; 
        } 
        return result; 
算法

那麼若是:如今變成存在2個不同的數字?數組

假設成x,y,那麼能夠O(n)求出x^y,由於x,y不一樣,因此異或的結果不爲0,當作2進制數,那麼找到第一位爲1 的位置,將這個位置設置爲劃分點,數組裏全部這個位置爲1 的異或一次,全部爲0的再異或一次,最終求出的兩個即爲兩個獨特的數字。性能

其實,我有個疑問?爲何多個不一樣的數字進行異或能去除重複的數字,通過搜索,原來還要根據異或運算的性質來講google

 

異或是一種基於二進制的位運算,用符號XOR或者 ^ 表示,其運算法則是對運算符兩側數的每個二進制位,同值取0,異值取1。它與布爾運算的區別在於,當運算符兩側均爲1時,布爾運算的結果爲1,異或運算的結果爲0。加密

簡單理解就是不進位加法,如1+1=0,,0+0=0,1+0=1。設計

性質htm

一、交換律

二、結合律(即(a^b)^c == a^(b^c))

三、對於任何數x,都有x^x=0,x^0=x

四、自反性 A XOR B XOR B = A xor  0 = A

異或運算最多見於多項式除法,不過它最重要的性質仍是自反性:A XOR B XOR B = A,即對給定的數A,用一樣的運算因子(B)做兩次異或運算後仍獲得A自己。這是一個神奇的性質,利用這個性質,能夠得到許多有趣的應用。 例如,全部的程序教科書都會向初學者指出,要交換兩個變量的值,必需要引入一箇中間變量。但若是使用異或,就能夠節約一個變量的存儲空間: 設有A,B兩個變量,存儲的值分別爲a,b,則如下三行表達式將互換他們的值 表達式 (值) :

 A=A XOR B (a XOR b)

 B=B XOR A (b XOR a XOR b = a) 

 A=A XOR B (a XOR b XOR a = b)

 相似地,該運算還能夠應用在加密,數據傳輸,校驗等等許多領域。

運用距離:

1-1000放在含有1001個元素的數組中,只有惟一的一個元素值重複,其它均只出現
一次。每一個數組元素只能訪問一次,設計一個算法,將它找出來;不用輔助存儲空
間,可否設計一個算法實現?

解法1、顯然已經有人提出了一個比較精彩的解法,將全部數加起來,減去1+2+...+1000的和。
這個算法已經足夠完美了,相信出題者的標準答案也就是這個算法,惟一的問題是,若是數列過大,則可能會致使溢出。
解法2、異或就沒有這個問題,而且性能更好。
將全部的數所有異或,獲得的結果與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的結果也是有規律的,算法比高斯定律還該簡單的多。
 
google面試題的變形:一個數組存放若干整數,一個數出現奇數次,其他數均出現偶數次,找出這個出現奇數次的數?
相關文章
相關標籤/搜索