剑指Offer10二进制中的1的个数

题目:

请实现一个函数,输入一个整数,输出该数二进制表示中1的个数,例如把9表示成二进制是1001,有2位是1,因此如果输入9,则输出2.

分析:

想法1:这个题很明显是位操作,当拿到这个题的时候我们可能会把这个数与1位与运算,然后把这个数右移一位,再做运算,直到这个数成为0.可是我们应该要注意的一个知识点,当这个数是整数的时候可以这么算,但是如果这个数是负数,那么它的右移操作就不是你想的那样了。比如00001010>>2 = 00000010;但是10001010 >>3 = 11110001,它的右移操作是用符号位来补充的。所以如果是负数的话,那么这个数右移操作会一直不是0,那么就是死循环了。

想法2:那么我们换一种思路来思考,既然不能让这个数右移操作,那么我们能不能把1左移操作。

下面是代码:

int Number1Fangfa1(int n)
{
    int flag = 1;
    int count =0;
    while(flag)
    {
        if(n&flag)
            count++;
        flag = flag<<1;
    }
    return count;
}


方法2:

其实这种思路是一种对二进制要非常了解,在做二进制减法的过程中,我们发现一个数减去1,总是把它从最右边数一直到第一个是1为止进行转化,比如1100减1,那么就是1011,这个结果和被减数本身,只有从右边数第一个是1开始才一样。所以我们可以利用这个结论来解决咱们的问题。一个数减去1之后,与其本身相与,会把该整数最右边一个1变成0.那么这个整数就会少了一个1.那么这个整数的二进制中有多少个1,就运算几次。

代码:

int Number1Fangfa2(int n)
{
    int count = 0;
    while(n)
    {
        count++;
        n = (n-1) & n;
    }
    return count;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值