1. 程式人生 > >嵌入式C面試題-計算無符號整形變數中1的個數

嵌入式C面試題-計算無符號整形變數中1的個數

考查位執行。這已經是一個非常常見的題目了,我這裡主要也是收集了多種解法。自己拿定,面試官最想看到的吧。

(1)懂C的都能寫出來的方式 ,這個時間複雜度花在迴圈上,由位數決定

int countBit(unsigned int n)

{

int count = 0;

while(n)

{

if(n&0x1)

count++;

n>>=1;

}

return count;

}

(2)更優秀一點的,我比較喜歡的。這個時間複雜度就有了優化,與n中一的位數有關。關鍵技巧點在n&=(n-1).  假如隨便看幾位n=000101,n-1=000100.  n&(n-1)=000100.所以可以看出,每次都是去掉了n中的低位的一個1.

int countBit(unsigned int n)

{

int count=0;

while(n)

{

n&=(n-1);

count++;

}

}

(3)有沒有常數時間呢,當然是有的,最簡單的就是想到用空間換時間。在《程式設計之美》裡面有講到這一方法,那是計算一個無符號8位的的值,建一個table[256],用n來做索引。這個方法 我不喜歡,想到這裡,我們32位,就很難實現了,空間代價太大了。換另一種實現方式(4)吧

(4)這裡就是數學的技巧和位運算的技巧了。

int countBit(unsigned int n)

{

int tmp = n;

        tmp = tmp - (tmp>>1) & 033333333333

                           - (tmp>>2) & 011111111111;

return ((tmp+tmp>>3) & 030707070707 )% 63;

}

我覺得第(2)(4)應該會給考官好的印像。

擴充套件 :給定兩個正整數A和B,請問至少要改變多少位,才能使A變成B。

int tmp=A^B;

countBit(tmp);

就是想要的結果。該拓展也是來自《程式設計之美》的問題。