二进制中1的个数

题目描述:输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。

负数的补码:减一取反  或者  取反加一

int 类型的范围是-231 ~ 231-1

我的做法:麻烦还不对

class Solution {
public:
     int  NumberOf1(int n) {
         if(n == 0)
             return 0;
         int num = 0;
         int con = n;
         bool flag = false;
         if(n % 2 == 1)
             num++;
         n = n/2;
         if(num == 1)
             flag = true;
         while(n)
         {
             if(n % 2 == 1)
                 num++;
             n = n/2;
         }
         if(con > 0)
             return num;
         else 
         {
             if(flag)
                 return 15-num+1+1;
             else
                 return 15-num+1;
         }
     }
};

正确解法1:

class Solution {
public:
     int  NumberOf1(int n) {
         int count=0;
         unsigned int flag=1;  
         while(flag){
             if (n & flag){
                 count++;
             }
          flag=flag<<1;
         }
         return count;
     }
};

正确解法2:

class Solution {
public:
     int  NumberOf1(int n) {
 
        int count = 0;
        while (n != 0) {
            ++count;
            n = (n - 1) & n;
        }
        return count;
     }
};

 下面的代码可以吗?:

    int NumberOf1(int n)
    {
        int count = 0;
        while(n)
        {
            if(n&1)
            {
                n>>1;
                count++;
            }
        }
        return count;
    }

不可以。当n为负数时,右移时在左边补1,这样就成了一个死循环,左边一直补1.

将右移一位换成除以2行吗?不好,位运算效率高

改正为正确解法1:。

解法1的循环次数为二进制的位数,优化为解法2,循环次数为二进制中1的个数。

解法1的循环跳出方式:

结论:一个数与一个数-1相与,得到的结果是正数的二进制最后一位的1变为0.

posted @ 2018-03-18 17:40  Lune-Qiu  阅读(142)  评论(0编辑  收藏  举报