N的二进制中1的个数

2019-04-14 20:39发布

解法一: 对于二进制数的操作,我们知道除以一个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
using namespace std;
int main()
{
int N,n=0;
while(cin>>N)
{
while(N)
{
N=N&(N-1);
n++;
}
cout<}
}