嵌入式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);
就是想要的結果。該拓展也是來自《程式設計之美》的問題。