问题描述
输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
(先给出最简单的代码)
package 剑指Offer;
import java.util.Scanner;
public class Erjinzhi02 {
public static int NumberOf1(int n) {
int sum=0;
char[]ch=Integer.toBinaryString(n).toCharArray();
for(int i=0;i<ch.length;i++)
{
if(ch[i]=='1')
{
sum++;
}
}
return sum;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
System.out.println(NumberOf1(n));
}
}
这里的核心就是用到一个函数toBinaryString()这个函数的意思是将十进制转化成二进制输出
Integer.toBinaryString(n)
这句话就是将n(十进制)转化成二进制,此时二进制使用字符串表示的。
char[]ch=Integer.toBinaryString(n).toCharArray();
这句话就是将表示二进制的字符串每个字符依次赋值给字符数组。
注意:
这个toBinaryString()函数功能强大无论是正数还是负数都可以求出他的二进制(其中负数的二进制是用其反码表示的)。
下面简要说明一下java整型的十进制转二进制
1、正数的十进制转二进制,就是不停的的对2取模,然后将余数逆着输出,针对这种过程。我自己写了一个关于求正数二进制的代码:
public static void getErjinzhi(int num)
{
Stack<Integer> s=new Stack<>();
int flag=num;
int sum=0;
while(flag!=0)
{
s.push(flag%2);
flag=flag/2;
}
while(!(s.isEmpty()))
{
System.out.print(s.pop());
}
}
这样对栈逆序输出就是正数的二进制
2、对于java中的整数,都是32位,也就是4个字节.所以255虽然二进制是11111111
但是实际上应该是00000000 000000000 00000000 11111111
再比如176的虽然二进制是10110000
但是实际上是00000000 00000000 00000000 10110000
但是我实验了,程序输出时候对于正数的二进制就是输入的11111111或10110000.不会有前面的补位0
(所以我们就知道其实是32就得了,输出还是最前面说的就是不停的的对2取模,然后将余数逆着输出)
3、0的二进制就是0;
4、但是对于负数那么情况大不相同(对于负数是不能直接求二进制,而是需要用它的补码来表示二进制)
5、负数补码的求法
(1)对于正数,补码=原码(就是二进制)
(2)对于负数求源码
1)求出对应正数的二进制(要求32位写全)
2)取反(0变1,1变0)
3)+1
比如-255:
对应正数的二进制:00000000 00000000 00000000 11111111(32位写全)
取反 11111111 11111111 11111111 00000000
加1 11111111 11111111 11111111 00000001(-255二进制(补码))
再例如-176:
对应正数的二进制:00000000 00000000 00000000 10110000
取反 11111111 11111111 11111111 01001111
加1 11111111 11111111 11111111 01010000(-176二进制(补码))
所以说toBinaryString这个函数牛逼就在于
不仅仅可以求出正数的二进制,也能求出负数的二进制(补码)
而且对于正数他就返回不需要0补位的(像255就是11111111),而要是负数他就是32位全输出(像-255就是00000000 00000000 00000000 11111111).
其他关于java二进制啥的比如>>,<<等操作参考一下的文章
添加链接描述