二進制中1的個數

題目描述 :

  輸入一個整數,輸出該數二進制表示中1的個數。其中負數用補碼錶示。

方法1:手動轉化法

  直接想到的就是手動把數轉化爲二進制存進vector裏,然後去數1的個數。當然這個很麻煩的地方在於負數是用補碼,你把絕對值轉化成二進制之後還得變成補碼,工作量太多。

方法2:整數移位法

  編程語言提供了位運算符,比如&(與)、|(或)、<<(左移)、>>(右移)等,位運算都是以二進制來操作的。
  我們可以把這個整數不斷右移,每右移一次就判定一次末尾是不是1,一直右移到這個數變成0。判定末尾的方法是和1作相與操作,與之後是1則說明原數這一位是1。
  代碼如下:

int count_one_way1(int num)
{
    int counts=0;
    while(num)
    {
        if((num&1)==1)
            counts++;
        num=num>>1;
    }
    return counts;
}

  但是這段代碼有問題,問題在於右移補位的時候,正數補0,而負數補1,所以如果num是個負數,會陷入死循環。

方法3:1移位法

  爲了避免上述問題,有一個改進方法是不移原來的數,我們把1這個數不斷左移,和原數的每一位作相與,然後每次想與的結果不是0,就說明原數這一位是1。
  代碼如下:

int count_one_way2(int num)
{
    int counts=0;
    int t=1;
    while(t!=0)
    {
        if((num&t)!=0)
            counts++;
        t=t<<1;
    }
    return counts;
}

  這裏會t會一直左移,本機int有多少位,t就會移動多少位,也就是會和num的每一位都比較到。

方法4:相鄰數相與法

  有一個很巧妙的方法是,n和n-1的相與結果,可以消掉n最右邊的1。比如說11-00&1011=1000。所以我們只需要不斷執行這種操作,就可以知道n有多少個1了。
  代碼如下:

int count_one_way3(int num)
{
    int counts=0;
    while(num)
    {
        counts++;
        num=num&(num-1);
    }
    return counts;
}

方法5:函數法

  c++有頭文件提供了這個功能,這裏尖括號裏是32是因爲我的電腦的int型是32位。

#include<bitset>
int count_one_way4(int num)
{
    return bitset<32>(num).count();
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章