题目
输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
思路
参考博客:传送门
负数直接处理会得出错误结果,java库函数得出的负数(int)二进制表示为其补码形式
原码、反码、补码
正数(或 0 ):
原码、反码、补码都一样,为常见二进制写法。
负数:
原码:符号位为 1 ,其余各位不变
反码:符号位不变(为 1 ),其余各位取反
补码:原码基础上,符号位不变(为 1 ),其余各位取反,加 1。 即为反码基础上加 1
位运算
-7 & 0x7FFFFFFF :
表示将 -7 转化为正数(非原来的数),但是其二进制数值基本不变(只有其符号位由 1 变为了 0)。这样就可以用处理正数的方法求 1 的个数了(需要加上符号位“消失”的 1 )
【画出其二进制表示即可想明白】
t = n & 1 等价于 t = n % 2
n = n >> 1 等价于 n = n / 2
public class Solution {
public static void main(String[] args) {
int n = 7;
System.out.println(NumberOf1(n));
}
// /**
// * 版本一:库函数
// * @param n
// * @return
// */
// public static int NumberOf1(int n) {
// int cnt = 0;
//
// String str = Integer.toBinaryString(n);
// char[] arr = str.toCharArray();
// for(int i=0; i<arr.length; i++) {
// if(arr[i] == '1')
// cnt ++;
// }
// return cnt;
// }
/**
* 版本二:位运算
* @param n
* @return
*/
public static int NumberOf1(int n) {
int cnt = 0;
if(n < 0) {
n = n & 0x7FFFFFFF; //见解释
cnt ++;
}
while(n > 0) {
int t = n & 1; //等价于 t = n % 2;
cnt += t;
n = n >> 1; //等价于 n = n / 2;
}
return cnt;
}
// /**
// * 版本三:库函数
// * @param n
// * @return
// */
// public static int NumberOf1(int n) {
// return Integer.bitCount(n);
// }
}
如有错误或不合理的地方,敬请指正~
加油!!