《剑指Offer》读书笔记11:二进制中1的个数


题目描述

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


解题思路

思路一:处理该整数
判断整数二进制表示的最右边一位是不是1,即将该整数与1(筛选因子)相与,然后右移一位。

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

思路二:处理该整数
把思路一的while循环改为一个for循环,可以解决死循环问题。
在for循环中,先计算出要整数的位数。

const size_t bitsInByte = 8;
int count = 0;
for (size_t i = 0; i < sizeof(int)*bitsInByte; i++ ) {
    if ( n & 1 ) {
        count++;
    }
    n >>= 1;
}
return count;

思路三:处理筛选因子
为了避免思路一的缺陷,我们可以对数字1动点手脚。
数字1与该整数最后一位相与后,对数字1进行左移一位。
循环次数为整数二进制的位数32。

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

思路四:处理整数最后一个1
每次只对最后一个1进行处理。
1. 一个整数减去1会发生什么变化呢?
二进制表示中,最后一个1变0,而原来1后面的0变1
例如,一个二进制数10101000,减去1后,变为10100111
2. 减去1之后的数与原数相与后,最后一个1会变为0,比最后一个1高位的位不变。
例如,10100111&10101000,结果为10100000,最后一个1已变为0。
见参考代码。


参考代码

class Solution {
public:
     int  NumberOf1(int n) {
        int count = 0;
        while ( n ) {
            count++;
            n = (n-1)&n;//将最后一个1置0
        }
        return count;
     }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值