剑指offer(11)——C++实现求解二进制中1的个数

题目

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

考察点

  • 二进制与位运算
    位运算:与(&)、或(|)、异或(^)、左移(<<)、右移(>>).
    左移(<<)规则:
    右边空出的位用0填补;高位左移溢出则舍弃该高位;计算机中常用补码表示数据。左移一位相当于乘以2.
    右移(>>)规则:
    左边空出的位用0或者1填补;正数用0填补,负数用1填补。注:不同的环境填补方式可能不同;低位右移溢出则舍弃该位。
  • 原码、反码与补码参考该博文
  • 思维缜密与自查

解题思路

  1. 第一反应是:将n和1进行位与操作,遇见一个1,计数就加1,然后将n左移一位,将当下最右继续与1进行位与操作。缺点是:当遇到负数会产生死循环!原因:负数的存储是有符号位的(最左一位为1),当进行左移时,为了保证其为负数不变,最左依然是1,循环下去左边会被1填满!
  2. 改进:n动,移动1.
  3. 另一种思路:依靠对原码、反码以及补码的充分理解。如果一个整数不为0,那么这个整数至少有一位是1。如果把这个整数减1,那么原来处在整数最右边的1就会变为0,原来在1后面的所有的0都会变成1。其余所有位将不会受到影响。

完整代码

/*11_二进制中1的个数*/
#include<iostream>
using namespace std;

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

int main()
{
	Solution s;
	cout << s.NumberOf1(3) << endl;
	cout << s.numberof1(12) << endl;
	return 0;
}

注意

  • 位操作是计算机中对数值的二进制形式操作。不用刻意将十进制转成二进制。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值