牛客网_剑指offer_二进制中1的个数

题目描述

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

解题思路

思路1:

由于是考虑二进制中1的个数,直接用一个无符号整形数字,从1开始左移,做一个遍历即可。
具体代码如下:

class Solution 
{
public:
     int  NumberOf1(int n) 
     {
         //负数用补码表示
         //负数补码:第一位表示符号,负数为1;补码表示全部取反,然后在取反的基础上加1
         unsigned int flag = 1;
         int count = 0;
         while (flag >= 1)
         {
             if ((n & flag) > 0)
             {
                 count++;
             }
             flag = flag << 1;
         }
         return count;
     }
};

思路2:

首先将整形数字n转化为无符号整形数字a;
在a的基础上不断的做a = a & (a - 1)的运算可以将a的最后一个1变为0,不断这样循环,一直到a == 0;即可得到其中的1的个数。
具体代码如下:

class Solution 
{
public:
     int  NumberOf1(int n) 
     {
         //负数用补码表示
         //负数补码:第一位表示符号,负数为1;补码表示全部取反,然后在取反的基础上加1
         int count = 0;
         unsigned int a = n;
         while (a != 0)
         {
             count++;
             a = (a - 1) & a;
         }
         return count;
     }
};

思路3:

合理利用标准库,将数字转化为字符串,再数字符串中的1的个数即可。具体详解写在了代码注释中,具体代码如下。

class Solution 
{
public:
    int  NumberOf1(int n) 
    {
         //负数用补码表示
         //负数补码:第一位表示符号,负数为1;补码表示全部取反,然后在取反的基础上加1

        string tmp;
        int count = 0;
        //用sizeof(long)来判断操作系统的位数4:32, 8:64
        //判断完位数之后将对应的数字转化为字符串
        if (sizeof(long) == 8)
            tmp = bitset<64>(n).to_string();
        else
            tmp = bitset<32>(n).to_string();
        
        //数字符串中的1的个数
        for (auto x : tmp)
        {
            if (x == '1')
                count++;
        }
        
        //考虑极端情况: -2147483648
        if (count > 32)
            return count - 32;
        return count;
    }
};

猜你喜欢

转载自blog.csdn.net/weixin_40349531/article/details/89513811