題目描述
輸入一個整數,輸出該數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;
}
}
}

-
反思
感覺這樣求,好蠢啊。。。。負數的補碼這麼惡心嗎,去看看大佬怎麼做。