位運算子之異或的化腐朽為奇妙

2021-09-08 04:38:56 字數 1905 閱讀 4978

記得lucida大神部落格寫過。函式式程式語言是ms面試題會涉及的東西。還有位運算。雖然我都不會運用。。

以下談一下異或的強大之處。總結來自july大神微博推薦**的一篇部落格。儘管博主是web開發者。可是這篇日誌數學技巧極強

先來一道leetcode通過率最高的題目,求乙個陣列中盡出現一次的數字。其它數字均出現兩次。

一看通過率最高,預計最簡單,然而本屌想破腦袋也沒想到能夠在o(n)時間o(1)空間的解法。有時還真的懷疑自己的智商了。可是從某july大神推薦的**部落格看到解法後,

三關禁毀。這尼瑪我沒怎麼用過位運算的ds壓根也想不到用異或來解。所以,我再次堅信,某些數學題,事實上看到解法都認為easy理解。可是你自己想出來的難度又是另當別論。有點類似於從起點找一條路徑到終點。而每前進一步都有n多種數學工具、演算法能夠使用,你的搜尋空間已經是指數級的了。所以做的題目一定要達到一定規模,才幹有感覺。

首先簡略說明異或運算的一點性質,當你學的時候,壓根認為就是數學理論,你根本不知道他幹嘛用:

1^x=1

0^x=x

a^b=b^a

a^b^c=a^(b^c)

對於上面的錯誤,博主表示很抱歉。犯了低階錯誤。為表示歉意及督促作用,博主放在這裡吃一塹 長一智

應該是1^x=~x 實在抱歉 博主寫得太快,一下激動犯錯了

另外以下的找兩個單獨出現一次的數的問題,主要是運用了0^x=x 的性質,將其它的都成對異或為0,僅僅剩下a或b, 然後0^x=x  所以異或就出結果了: )

上面的性質都是顯然的。回到這道leetcode題,有了這個就有個驚人發現:

a^b^c^c^a^d^b=a^a^b^b^c^c^d=d!!!!(你能夠多次運用交換律。結合律獲得這一性質)

沒錯,僅僅要所有異或,就是要的答案。**不能再簡單了。附上本吊的**:

int singlenumber(int a, int n)

然後如今回憶起來原來都看過這個題目及解法(不用變數交換兩個變數的值)。僅僅是當時沒有summary和write下來。如今總結在這裡。只是後者可能會有溢位,所以位運算是最好的演算法.這裡假設大家剛開始接觸程舍可能會非常費解。和數學思維非常不同。我當初也是問c++老師,交換ab不久a=b b=a 為啥還要tmp,老師說會覆蓋掉原值(好吧,請原諒我那時的幼稚==),由於程舍是電腦科學。電腦科學都是以馮諾依曼機模型,是須要儲存,輸入輸出的。和數學光在腦子裡思考不一樣,習慣之後就好了。

以下在擴充套件一道題目,從乙個僅僅有兩個數字僅出現一次,其它數字都出現兩次的陣列中找出這兩個出現一次的數字

第一反應又是抑或運算,然而所有異或得到的是a^b, 怎麼把他們分開,又聯想到交換a b值的case,這次會複雜一些,解法是先看a^b值中位為1的那麼位置。

發現這些位置a b不同,其它位置都同樣。而其它2*n個運算異或結果為0。因此通過異或這一位為1的數。就能夠得到a 或b了(大家能夠思考下為什麼),假如得到a, 再a^ (a^b)就得到b了。最難想的就是怎麼先得到a b 中的乙個

貼上別人的**。當中選擇了低位中第乙個為1的位置,事實上不論什麼乙個1都是能夠的,並且裡面求000001還用了點位運算知識。num&~(num-1) 

int getfirstonebit(int num) //輸出 num 的低位中的第乙個 1 的位置  

void findtwo(int *array, int length)

assert(axorb != 0); //保證題目要求,有兩個single的數字

firstonebit = getfirstonebit(axorb);

for (int i = 0; i < length; ++i)

}b = axorb ^ a;

cout << "a: " << a << endl;

cout << "b: " << b << endl;

}

按位異或運算子

參與運算的兩個值,如果兩個相應位相同,則結果為0,否則為1。即 0 0 0,1 0 1,0 1 1,1 1 0 例如 10100001 00010001 10110000 0 0 0,0 1 1 0異或任何數 任何數 1 0 1,1 1 0 1異或任何數 任何數取反 任何數異或自己 把自己置0 1 ...

按位異或運算子

2 實現兩個值的交換,而不必使用臨時變數。例如交換兩個整數a 10100001,b 00000110的值,可通過下列語句實現 a a b a 10100111 b b a b 10100001 a a b a 00000110 3 在組合語言中經常用於將變數置零 xor a,a 1 static i...

異或運算子和位運算子詳解

一.異或運算子 1.異或運算子是用符號 表示的,其運算規律是 轉換成二進位制的形式來對比每一位數,相同則結果為0,不同則結果為1。分析 a 的值是15,轉換成二進位制為 1111,而b 的值是2,轉換成二進位制為 0010,根據異或的運算規律,可以得出其結果為 1101 即最終 a b的值為13 二...