1. 程式人生 > >[LeetCode-191] Number of 1 Bits(判斷一個整數中有多少個1)

[LeetCode-191] Number of 1 Bits(判斷一個整數中有多少個1)

Write a function that takes an unsigned integer and returns the number of ’1’ bits it has (also known as the Hamming weight).

For example, the 32-bit integer ’11’ has binary representation 00000000000000000000000000001011, so the function should return 3.

方法一:【分析】判斷一個整數最右邊是不是1,我們可以把輸入的整數和1相&,判斷相&之後的結果,判斷是不是為1,然後繼續移位判斷其它位
程式碼如下:

/*方法1.移位,僅適用正數*/
int hammingWeight(uint32_t n) 
{
    uint32_t temp  = n;
    int NumberOfOne = 0;
    /*輸入是一個無符號的數,故不會出現死迴圈*/
    while(temp) {
        if(temp & 1) {
            NumberOfOne ++;
        }
        temp = temp>>1;
    }
    return NumberOfOne;
}

方法二:【分析】上述的方法只適用於正數,當輸入的數為一個負數的時候,比如按照方法一分析得,0x8000-0000,當右移一位變成0x0400-0000,其實不是這樣的,因為移位前是一個負數,所以我們要保證移位後的數也是一個負數,因此移位後改數變為0xC000-0000.最高位永遠都是1,最終這個數字會變成0xFFFF-FFFF,程式陷入死迴圈。

為了避免這種情況出現,我們對程式碼進行改進,我們不移動輸入的數字,我們將輸入數字n和1相&,再判斷是不是1,然後將1移位變成2(0001->0010),再與n相&,因此類推。
程式碼如下:

/*方法2.移位,對於負數也適用*/
int hammingWeight(int32_t n) 
{
    int NumberOfOne = 0;
    uint32_t flag = 1;

    while(flag) {
        if(n & flag) {
            NumberOfOne ++;
        }
        flag = flag << 1
; } return NumberOfOne; }

方法三:【分析】我們將一個整數減去1,都是把最右邊的1變成0,如果它右邊還有0,所有的0全部變成1,但是它左邊數字均保持不變。我們把這個整數和它減去1的結果想&的話,可以得到最右邊的1。
程式碼如下:

/*方法3.移位,對於負數也適用*/
int hammingWeight(int32_t n) 
{
    int NumberOfOne = 0;

    while(n) {
        NumberOfOne ++;
        n = n&(n-1);
    }
    return NumberOfOne;
}