第14個算法 二進制中1的個數

編寫一個函數,輸入是一個無符號整數,返回其二進制表達式中數字位數爲 ‘1’ 的個數(也被稱爲漢明重量)。java

 

示例 1:函數

輸入:00000000000000000000000000001011
輸出:3
解釋:輸入的二進制串 
00000000000000000000000000001011 中,共有三位爲 '1'。

示例 2:.net

輸入:00000000000000000000000010000000
輸出:1
解釋:輸入的二進制串 00000000000000000000000010000000 中,共有一位爲 '1'。

示例 3:code

輸入:11111111111111111111111111111101
輸出:31
解釋:輸入的二進制串 11111111111111111111111111111101 中,共有 31 位爲 '1'。

 

提示:blog

  • 請注意,在某些語言(如 Java)中,沒有無符號整數類型。在這種狀況下,輸入和輸出都將被指定爲有符號整數類型,而且不該影響您的實現,由於不管整數是有符號的仍是無符號的,其內部的二進制表示形式都是相同的。
  • 在 Java 中,編譯器使用二進制補碼記法來表示有符號整數。所以,在上面的 示例 3 中,輸入表示有符號整數 -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表示「負」,而數值位,三種表示方法各不相同。在計算機系統中,數值一概用補碼來表示和存儲。緣由在於,使用補碼,能夠將符號位和數值域統一處理;同時,加法和減法也能夠統一處理。此外,補碼與原碼相互轉換,其運算過程是相同的,不須要額外的硬件電路。特性一、一個負整數(或原碼)與其補數(或補碼)相加,和爲模。二、對一個整數的補碼再求補碼,等於該整數自身。三、補碼的正零與負零表示方法相同。

相關文章
相關標籤/搜索