1. 程式人生 > >位運算筆試練習——判斷兩個整數(32位)的二進位制表達有多少個位不同?

位運算筆試練習——判斷兩個整數(32位)的二進位制表達有多少個位不同?

實習生筆試題
這裡寫圖片描述

問題引入

1、二進位制表達方式——位運算
2、有多少位不同——好像只能一位一位的取比較
3、如何取得一個數的每一位呢?
4、比較完一位之後,能否把這一位去掉,比較剩下的,然後重複整個過程呢?

思考一:

判斷一個整數二進位制表達中有多少位是1?

直接上——a = a & (a - 1)
這個表示式的意思是:將a的二進位制表達中最右邊的1(包括1)後面的位變成0;
看圖很容易理解:
這裡寫圖片描述

這樣就能理解了a = a & (a-1) :其實就是一個把a二進位制表達中從低到高位的所有1變成0的過程,直到a變為0。

顯然,a的二進位制表達中1的個數就等於這個變換(直到把a變為0)的次數。

下面給出判斷一個整數二進位制表達中有幾位是1;

#include <stdio.h>
//統計一個數的二進位制數中的1的個數
int Count(int n) {
    int sum = 0;
    while(n) {
        sum++;
        n &= (n - 1);
    }
    return sum;
}

int main (void) {
    printf("%d\n",Count(5));
    return 0;
}
// 5——0000 0110 兩位有1
// printf()輸出 2 

a &= (a -1)還可以用來判斷一個數x是否是2的n次方

判斷一個數(x)是否是2的n次方
-------------------------------------
#include <stdio.h>

int func(int x)
{
    if( (x&(x-1)) == 0 )
    //如果一個數是2的n次方,那麼這個數用二進位制表示時其最高位為1,其餘位為0。
    //== 優先順序高於 &
        return 1;
    else
        return 0;
}

int main()
{
    int x = 8;
    printf("%d\n", func(x));
}

思考二:

異或——如果a、b兩個值不相同,則異或結果為1。如果a、b兩個值相同,異或結果為0。
temp = a ^ b;則temp的二進位制表示式中1的個數就是兩數二進位制表示式不同的位的總數

#include <stdio.h>
int CountBitDiff(int n, int m);

int main (void) {
    printf("%d\n", CountBitDiff(1999,2299));
    return 0;
}

int CountBitDiff(int n, int m) {
    int temp = n ^ m;
    int sum = 0;
    while (temp) {
        sum ++;
        temp &= (temp - 1);
    }
    return sum;
}

思考三:

對於temp = a ^ b; 如何統計temp二進位制表示式中1的個數?
另一種思路:
每次只判斷最低位,然後向右移位,知道temp為0;

#include <stdio.h>

int CountBitDiff(int n, int m) {
    int re  = m ^ n;//  第一次之後,每次都要移位,所以用re表示剩餘的,
    int sum = 0;
    while (re) {
        if ( (re & 1) == 1 ) { 
            //re & 1如果re最低位是1,則結果等於1,表示該位不同sum++;
            sum++;
        } 
        re = re >> 1;//向右移位

    }
    return sum;
}

int main(void) {
    printf("%d\n", CountBitDiff(1,2));
    return 0;
}