1. 程式人生 > >【程式設計之美】任意給定一個32位無符號整數n,求n的二進位制表示中1的個數

【程式設計之美】任意給定一個32位無符號整數n,求n的二進位制表示中1的個數

任意給定一個32位無符號整數n,求n的二進位制表示中1的個數,比如n = 5(0101)時,返回2,n = 15(1111)時,返回4。這也是一道比較經典的題目了,相信不少人面試的時候可能遇到過這道題吧,我今天就遇到了,當時懵了。現在想想多簡單,浪費了一次機會。

1.普通法

相當於向右移出來一個,計數器加一個。

這種方法最簡單,就是通過移位+計數。首先把n於1相&,如果結果==1,說明最後一位是1,計數器+1;然後右移一位,最後一位就沒有了,前面用0填充,在進行&操作。迴圈。這種方法的運算次數與輸入n最高位1的位置有關,最多迴圈32次。


2.快速法

相當於從最右邊的1開始,清除一個1,計數器加1.

至於怎麼清除通過n與n-1相&,eg.7(0111)&6(0110),那麼7的最右邊的1就清除了。

這種方法速度比較快,其運算次數與輸入n的大小無關,只與n中1的個數有關。如果n的二進位制表示中有k個1,那麼這個方法只需要迴圈k次即可。其原理是不斷清除n的二進位制表示中最右邊的1,同時累加計數器,直至n為0,程式碼如下

3.靜態表_8bit

對於32位的數要分成四組 8,8,8,8的。 8位無符號數表示範圍0-255這256個數,建立一個table陣列,盛放這256個數的1的個數,下表即該數。第一組,直接n & 0xff就能得到1所在的位置。取得最低位的8bit,累加後繼續移位,

第二組要把n向右移8位,再與0xff相&即可。第三組把n向右移16位,再與0xff相&即可。第四組把n向右移24位,再與0xff相&即可。如此往復,直到n為0。

所以對於任意一個32位整數,需要查表4次。以十進位制數2882400018為例,其對應的二進位制數為10101011110011011110111100010010,對應的四次查表過程如下:紅色表示當前8bit,綠色表示右移後高位補零。

第一次(n & 0xff)             10101011110011011110111100010010

第二次((n >> 8) & 0xff)  00000000101010111100110111101111

第三次((n >> 16) & 0xff)0000000000000000

1010101111001101

第四次((n >> 24) & 0xff)00000000000000000000000010101011