劍指offer編程題 -- 二進制中1的個數

題目描述:

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

注意:整數在計算機中本身就是以二進制形式存儲的。

主要使用的是位運算。

補碼的移位:

左移:正負數均是在右邊補0;

右移:正數是在左邊補0,負數是在左邊補1。

 

方案1:

依次將1左移,與該數做&運算。

class Solution {

public:

     int  NumberOf1(int n) {

         int count = 0;

         int tmp = 1;

         while(tmp){

             if(n & tmp){

                 count++ ;

             }

             tmp = tmp << 1;

         }

         return count;

     }

};

運行時間:4ms

佔用內存:480K

方案2:該數與1做&運算,但要注意循環條件,因爲當爲負數時,負數右移左邊補1,所以可能陷入無限循環,因此需要控制其位數。該方案需要一共執行判斷32次。

class Solution {

public:

     int  NumberOf1(int n) {

         int count = 0;

         int tmp = 0;

         while(tmp < 32){

             if(n & 1){

                 count++ ;

             }

             n = n >> 1;

             tmp++;

         }

         return count;

     }

};

運行時間:3ms

佔用內存:384K

方案3:x&(x-1)可以將整數的最右邊的1變爲0,根據這個,我們只需循環判斷x = x&(x-1) 是否爲0,即可統計1的個數。該方案相比方案2而言減少了循環的次數。

 

 

eg:-5二進制中1的個數。

x

x&(x-1)

0101

0101 & 0100 = 0100

0100

0100 & 0011 = 0000

 

class Solution {

public:

     int  NumberOf1(int n) {

         int count = 0;

         while(n){

             count++;

             n = n & (n-1);

         }

         return count;

     }

};

運行時間:3ms

佔用內存:480K

 

方案4:使用輾轉相除法。

注意:該方案只能用於正數,不能用於負數。

eg: -1 % 2 != 1,count =0;但實際上-1的二進制中有32個1。

class Solution {

public:

     int  NumberOf1(int n) {

         int count = 0;

         while(n){

           if(n % 2 == 1){

              count++;

}

           n = n/2;

}

     

         return count;

     }

};

參考鏈接:

http://www.cnblogs.com/AndyJee/p/4630568.html

https://blog.csdn.net/zhao_miao/article/details/79747664

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章