N的二进制中1的个数

解法一:

对于二进制数的操作,我们知道除以一个2,原来的位数将会减少一位,如果除的过程中有余数,那么就表示当前位置有一个1,否则为0。

以10100010为例:
第一次除以2时,商为1010001,余0。
第二次除以2时,商为101000,余1。

第三次除以2时,商为10100,余0。

第四次除以2时,商为1010,余0。
第五次除以2时,商为101,余0。
第六次除以2时,商为10,余1。
第七次除以2时,商为1,余0。
第八次除以2时,商为0,余1。

解法二:

采用位操作。
以10100001为例:
右移一位,结果为1010000,移出位为1
再右移一位,结果为101000,移出位为0
再右移一位,结果为10100,移出位为0
………
比上面更好的解决了问题,还有更简单的做法吗?

解法三:

位操作虽然比除,求余操作的效率高了很多。但是,时间复杂度没有改变,时间复杂度还是O(log2v),log2v为二进制的位数。现在我们想设计出一种算法解决这个问题时,只与二进制表达式中的1的个数有关的(先介绍按位与)
以10100001为例:
  10100001    10100000   10000000
&10100000 &10011111 &01111111
  10100000    10000000   00000000

解法四:

也许你感到上面的算法已经足够快了,但是这是最好的解法吗?难道不能设计出O(1)的解法,即当你输入一个数时,对应的结果也知道了。




扩展问题:给你两个整数A和B,问把A变成B需要改变多少位。

解放三代码:

#include<iostream>
using namespace std;
int main()
{
int N,n=0;
while(cin>>N)
{
while(N)
{
N=N&(N-1);
n++;
}
cout<<n<<endl;
}
}

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值