剑指offer 题15——二进制中1的个数

二进制中1的个数

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

有这样一个段子:
世上有10种人,一种人知道二进制,而另一种人不知道二进制

二进制运算是十分重要的。
高效而便捷

如果我们按部就班,只看最后一位,但判断之后进行移位,直到最后数完。可以写出以下代码:

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

看起来似乎没啥问题,但是如果是负数的话,比如0x80000000,当右移一位的时候,不是变成0x40000000,而是0xC0000000,那么到最后就会变成0xFFFFFFFF。显然这样会陷入死循环。


那么我们可以引进一个flag值,这样可以避免死循环。先将flag置为1,这次每次循环讲flag左移,与n作与,这样就能将1的个数统计出来了
代码如下:

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

这样在32次(或者63次)循环之后,就可以将1的个数数出来了。

但是毕竟还是循环了32次,有没有什么办法,减少循环次数呢?

其实在按位运算时,有许多的技巧,比如我们现在可以用到一条:
对于一个n,如果要去掉n的二进制最后一个1,可以这样获得(n-1)&n。

那么就可以得到下面的代码:

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

这样有多少个1就循环几次。大大减少了循环次数。
————————————————————————————————————————————
参考书籍《剑指offer》

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值