题目描述
输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
思路分析
必须要知道的常识!计算机中数值一律用补码存储!所以不用特别关心负数的表示!
看解析才知道,基本上有三种做法。
基础思路是,每一位和1进行与运算,为1则便是该位是1,count++。出现的问题是,>>有符号右移后,正数左边补0,负数左边补1。若数为负数,则陷入死循环。
- 做法一:无符号右移。右移后,无论正数还是负数,左边都补0。
- 做法二:32次左移判断1。int类型有32位,无论正负都从低往高左移判断32次。
- 做法三:n & n-1,会把n最右边的一个1变成0。则一个整数有多少个1,就做多少次这样的操作。
代码实现
/**
* 无符号右移。正负数都补0.
* @param n
* @return
*/
public static int NumberOf1(int n) {
int count = 0;
while (n != 0) {
count += (n & 1);
n = n >>> 1;
}
return count;
}
/**
* 进行32次左移判断
* @param n
* @return
*/
public static int NumberOf12(int n) {
int count = 0, flag = 1;
while (flag != 0) {
count = (n & flag) != 0 ? count + 1 : 0;
flag <<= 1;
}
return count;
}
/**
* n & n-1 ,会把n最右一个1变成0
* @param n
* @return
*/
public static int NumberOf13(int n) {
int count = 0;
while (n != 0) {
count++;
n = (n - 1) & n;
}
return count;
}