题目描述
输入一个整数,输出该数32位二进制表示中1的个数。其中负数用补码表示。
我10秒钟做出了正数的1的个数,却秀死在负数。。。
public class Solution {
public int NumberOf1(int n) {
//正数好做,爽死了
if(n>=0){
int c=0;
while(n>0){
if(n%2==1){
c++;
}
n=n/2;
}
return c;
}else{//负数就不好玩了
//先处理-0
//+0是0,而-0定义为-2^32
if(n==(-2147483648))
return 1;
//开始操作起来,字符串不是玩的很溜吗
StringBuilder sb = new StringBuilder();
n=-n;//负数取反的正数
while(n>0){
sb.append(n%2);
n=n/2;
}
String str = sb.toString();//计算得该正数的逆序原码,若高位补上1就是负数的原码了
sb = new StringBuilder();
//sb用来存储调好顺序的源码,记得此处前面符号位1没加,和0没加
for(int i=str.length()-1;i>=0;i--){
sb.append(str.charAt(i));
}
//来补位了
StringBuilder sb2 = new StringBuilder();
//先把符号位1加上
sb2.append(1);
//剩余的位数0补充,凑齐32位
int size = sb.toString().length();
for(int i=0;i<31-size;i++){
sb2.append(0);
}
sb2.append(sb);//真正的负数源码
//下面开始取反了,注意符号位第一位不变
for(int i=1;i<sb2.length();i++){
if(sb2.charAt(i)=='0'){
sb2.setCharAt(i,'1');
}else{
sb2.setCharAt(i,'0');
}
}
//sb2是取反之后的反码
//进行+1
boolean flag = true;
for(int i=sb2.length()-1;i>0;i--){
if(flag){
if(sb2.charAt(i)=='0'){
sb2.setCharAt(i,'1');
flag=false;
}else{
sb2.setCharAt(i,'0');
flag=true;
}
}
}
//来统计1的个数吧
int c=0;
for(int i=sb2.length()-1;i>=0;i--){
if(sb2.charAt(i)=='1'){
c++;
}
}
return c;
}
}
}
- 反思
感觉这样求,好蠢啊。。。。负数的补码这么恶心吗,去看看大佬怎么做。