編寫一個函數,輸入是一個無符號整數,返回其二進制表達式中數字位數爲 ‘1’ 的個數(也被稱爲漢明重量)。java
示例 1:函數
輸入:00000000000000000000000000001011 輸出:3 解釋:輸入的二進制串 00000000000000000000000000001011 中,共有三位爲 '1'。
示例 2:.net
輸入:00000000000000000000000010000000 輸出:1 解釋:輸入的二進制串 00000000000000000000000010000000 中,共有一位爲 '1'。
示例 3:code
輸入:11111111111111111111111111111101 輸出:31 解釋:輸入的二進制串 11111111111111111111111111111101 中,共有 31 位爲 '1'。
提示:blog
-3
。
思路:看到二進制字眼,通常都是考察的位運算。get
思路一:將n和1與(&)運算,而後再右移;其中,若是運算結果是1則代表n的最後一位是1,count+1;不然就是最後一位是0,count不變.編譯器
缺陷:這種沒有考慮到n是負數的時候。在計算機中負數存儲成補碼,右移的時候補位是1而不是0,因此1會一直存在,這樣會形成一直循環,致使陷入死循環。博客
思路二:將n和1與(&)運算,能夠n不動,讓1左移,其中,若是運算結果是1則代表n的最後一位是1,count+1;不然就是最後一位是0,count不變.it
java與無符號那些事編譯
public int NumberOf1(int n) {
int count=0;
while(n!=0){
++count;
n=n&(n-1);
}
return count;
}
思路三:一個整數減去1,至關於把這個數最右邊的1的後邊的變成0,0變成1;1的前邊的0,1不變。舉例說明:1100,減去1,變成1011。將這兩個數作與&運算,1100&1011會獲得1000,能夠看出把1100最右邊的1變成了0,因此咱們能夠用n&(n-1)來計算有多少個1;n能運行多少次這樣的操做,就有多少個1.
public int NumberOf1(int n) {
int count=0;
while(n!=0){
++count;
n=n&(n-1);
}
return count;
}
相關知識:
http://blog.csdn.net/xubinlxb/article/details/50824980這篇博客說的二進制右移很清楚。
原碼與補碼的相互轉換:
分兩種狀況,以八位原碼轉換爲例:正數(符號位爲0的數)補碼與原碼相同.負數(符號位爲1的數)變爲補碼時符號位不變,其他各項取反,最後在末尾+1例如:原碼01100110,補碼爲:01100110原碼11100110,先變反碼:10011001,再加1變爲補碼:10011010計算機中的符號數有三種表示方法,即原碼、反碼和補碼。三種表示方法均有符號位和數值位兩部分,符號位都是用0表示「正」,用1表示「負」,而數值位,三種表示方法各不相同。在計算機系統中,數值一概用補碼來表示和存儲。緣由在於,使用補碼,能夠將符號位和數值域統一處理;同時,加法和減法也能夠統一處理。此外,補碼與原碼相互轉換,其運算過程是相同的,不須要額外的硬件電路。特性一、一個負整數(或原碼)與其補數(或補碼)相加,和爲模。二、對一個整數的補碼再求補碼,等於該整數自身。三、補碼的正零與負零表示方法相同。