最近刷力扣时 遇到了好几个题目都是计算 数字 的二进制形式中 1的个数,所以特意在此记录一下。
其实最基本的办法就是先求出 数字的二进制,然后去对每一个字符去遍历判断是否为1就可以了,现在就是需要先计算出 数字的二进制形式。
数字转换为二进制:
- 正整数转二进制 : 正整数只需要一直除以二 取余 然后将余数 倒序排列就可以了。
例如 : 13 转为二进制 的话 13%2 = 1 ,13/2 = 6, 6%2=0, 6/2=3, 3%2=1, 3/2= 1,1%2= 1,1/2=0,将余数倒序排列就是 1101
public String getBinaryString(int n){
String binary = "";
while(n>0){
binary = n%2 + binary;
n = n/2;
}
return binary;
}
- 负整数转二进制 : 负整数转二进制是在 他的绝对值 转二进制 的补码,就是在正整数的二进制基础上进行取反 再 +1.
例如 : 13 转为二进制 的话 13%2 = 1 ,13/2 = 6, 6%2=0, 6/2=3, 3%2=1, 3/2= 1,1%2= 1,1/2=0,将余数倒序排列就是 1101
//求负整数 二进制字符串 正整数求法然后 再取补码(取反+1)
public String getFuBinaryString(int n){
n = -n;
String binary = "";
char[] chars = new char[33];
Arrays.fill(chars,'0');
int index = 32;
while(n!=0){
chars[index--] = (n%2+ "").charAt(0) ;
n = n/2;
}
for (int i = 1; i < 33; i++) {
chars[i] = chars[i]=='0'?'1':'0';
}
chars[32] = getSum(chars[32]);
for (int i = 31; i >0 ; i--) {
if (chars[i]=='2'){
chars[i] = '0';
chars[i-1] = getSum(chars[i-1]);
}else{
break;
}
}
return String.valueOf(chars).substring(1);
}
//求符号 0 1 +1后的结果
public char getSum(char a){
char res = '0';
switch (a){
case '0':
res = '1';
break;
case '1':
res = '2';
break;
}
return res;
}
上述是基本的求二进制 的办法,之前刷力扣看到了更简单的布莱恩尼根算法,特此记录一下
布莱恩·克尼根位计数算法
布莱恩·克尼根位计数算法的基本思想是:使用特定比特位和算术运算移除等于 1 的最右比特位。
比如要计算x:10001000 10001000的“1”个数:
x:10001000 10001000
x-1: 10001000 10000111
那么x&x-1的值为ans=10001000 10000000.
如此循环直到ans的值为0,每次count+1即可记录x中原有的1数量;
代码实现 求二进制数中 1的个数 力扣 191. 位1的个数
public class Solution {
public int hammingWeight(int n) {
int count = 0;
while (n!=0){
n = n & n-1;
count++;
}
return count;
}
}
这是布赖恩·克尼根位计数算法的基本思想。该算法使用特定比特位和算术运算移除等于 1 的最右比特位。 当我们在 number 和 number-1 上做 AND 位运算时,原数字 number 的最右边等于 1 的比特会被移除。
在平常开发中还有更加简单的方法,Inerger 封装类 实现了 bitCount方法和toBinaryString方法,前者是计算二进制中1的个数,后者是将数字转为 二进制字符串,都只需要传参数 数字就可以。
public static void main(String[] args) {
System.out.println(Integer.bitCount(9)); // 2
System.out.println(Integer.toBinaryString(9)); // 1001
}