1. 程式人生 > >位運算的巧妙用法

位運算的巧妙用法

例1:在一個數組中若一個數只出現了一次其它的數都出現的了兩次那麼如何才能快速的找到這個數

  方法:從前向後兩個數依次進行異或最後的結果就是要找的那個數

若陣列中的數字依次為 :5,6,4,2,2,5,6 

首先將 5,6進行異或  結果 011  011和4進行異或 111 111和2進行異或 101 101和2進行異或111 111和5進行異或010 010 和6進行異或是100 結果為4 

經過上述的運算我們不難發現兩個相同的數進行異或就會互相消除那麼最後就會留下那個單獨的數

例2:那麼如果這個陣列中單獨的數不止一個那麼我們該怎麼做才能找出這兩個數呢?

根據上個題的做法我們要是從前向後進行異或那麼我們得到的一定是這兩個只出現一次的數的結果那麼我們如何將這兩個數進行分離 ?

假如上面的陣列中還有一個數是3那麼現在的陣列中就存在兩個單獨的數了 我們再將前面的結果與3進行異或我們何以得到結果為111  這個異或的結果代表什麼意思?代表這兩個單獨的數二進位制中(1,2,4)這三個位都不一樣那麼我們可以任選其中的一位對整個陣列進行分組 我們可以選擇(1)位為1的為一組 (1)位為0的分為一組這樣我們就將單獨出現的而個數分為了不同的兩組

即 5 5 3 為一組   2 2 4 6 6 為一組這樣我們就將這個問題轉化成了若有一個數出現一次的問題

例3:不用加減乘除法實現兩個數的加法運算

首先看十進位制是如何做的: 5+7=12,三步走
第一步:相加各位的值,不算進位,得到2。
第二步:計算進位值,得到10. 如果這一步的進位值為0,那麼第一步得到的值就是最終結果。第三步:重複上述兩步,只是相加的值變成上述兩步的得到的結果2和10,得到12。同樣我們可以用三步走的方式計算二進位制值相加: 5-101,7-111 第一步:相加各位的值,不算進位,得到010,二進位制每位相加就相當於各位做異或操作,101^111。第二步:計算進位值,得到1010,相當於各位做與操作得到101,再向左移一位得到1010,(101&111)<<1。第三步重複上述兩步, 各位相加 010^1010=1000,進位值為100=(010&1010)<<1。繼續重複上述兩步:1000^100 = 1100,進位值為0,跳出迴圈,1100為最終結果。

例四:不用中間變數交換兩個數

void swap(int& a, int& b)              //只用加法、減法、乘法也可以交換兩個值
{    a = a + b;
    b = a - b;
    a = a - b;
}
void swap(int& a, int& b)              //使用位運算也可以交換兩個值
{    a = a^b;
    b = a^b;
    a = a^b;
}