题目描述
输入一个整数,输出该数二进制表示中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; } }