题目
请实现一个函数,输入整数,输出二进制表示中1的个数。
思路1
复习左移操作和右移操作:
左移:右边补0
右移:如果是无符号数,直接补0;如果是符号数,用符号补。
不断与1做 与运算,然后计数,然后将数字右移一位。注意将数字除以2也一样,但是右移操作更加有效率。
但是当输入数字是负数时,最左位是1,不断与1做”与“运算会陷入死循环。
class Solution { public: int NumberOf1(int n) { // 当输入负数时,会引起死循环 int count = 0; while( n != 0){ if ( n & 1){ count++; n = n >> 1; } } return count; } };
思路2
让n不断与1、10、100、1000做与运算。
缺点:如果是32位的整数,就需要循环32次。
class Solution { public: int NumberOf1(int n) { int count = 0; unsigned int flag = 1; while (flag){ if (n & flag){ count++; } flag = flag << 1; } return count; }
思路3
把该数字和自己减去1后,做与运算。效果相当于把最右边的1变成0。
class Solution { public: int NumberOf1(int n) { int count = 0; while (n){ count++; n = n & (n-1); } return count; }
拓展
1、用一条语句判断一个整数是不是2的整数次方:
因为2的整数次方只有一个1,因此只需要判断 n & (n-1)之后是否为0;
2、输入两个整数m与n,计算需要改变m的二进制中多少位才能得到n:
将两个数字做异或,然后用思路3的做法统计1的个数,这就是他们不同的位数。