(原)剑指offer之位运算

题目描述

输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
 
思路:
count为1的位数,初始为零
每次右移一为,与1做与运算,结果不为零说明最后一位为1
c++代码如下
 
int numberofone(int n){
  while (n){
      if (n & 1) count++;
      n>>1       
  }
return count;
}

上面这种方法有个缺点比如输入一个负数由于负数最高符号位为1,每次移位总是补全符号位,因此最终此负数会变为全1,也就陷入了死循环。

避免死循环的算法;

可以逐位判断:先判断最后一位,与1与然后倒数第二位与2相与以此类推。

代码

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

奇思妙想的解法:

一个整数如果最后一位为1,则减去1最后一位变为零其他位不变,如果最后一位不为1,减去1最右为1的一位变为零,之后的位都变为1,

如果我们把一个数减1的结果如原来的数做与运算,得到的结果总是把最右边为1的哪一位变为零,其他位不变。也就是说一个数有多少个1就能做多少次这样的运算。

算法实现.

int numberone(int n){
     int count = 0;
     while (n){
           count++;
           n = n - 1;
}    
}
原文地址:https://www.cnblogs.com/code-changeworld/p/4552075.html