位1的個數 邏輯位運算符

邏輯位運算符

位運算就是對二進制數執行計算,是整數的逐位運算。

圖片.png

& 按位與

如果兩個相應的二進制位都為1,則該位的結果值為1,否則為0。


carbon(2).png

| 按位或

兩個相應的二進制位中只要有一個為1,該位的結果值為1。


carbon(2).png

^ 按位異或

若參加運算的兩個二進制位值相同則為0,否則為1。


carbon(2).png

~ 取反

~是一元運算符,用來對一個二進制數按位取反,即將0變1,將1。


carbon(3).png

<< 左移

用來將一個數的各二進制位全部左移N位,右補0。


carbon(3).png

>> 右移

將一個數的各二進制位右移N位,移到右端的低位被舍棄,對于無符號數, 高位補0。


carbon(3).png

位1的個數

編寫一個函數,輸入是一個無符號整數(以二進制串的形式),返回其二進制表達式中數字位數為 '1' 的個數(也被稱為漢明重量)。
提示:
請注意,在某些語言(如 Java)中,沒有無符號整數類型。在這種情況下,輸入和輸出都將被指定為有符號整數類型,并且不應影響您的實現,因為無論整數是有符號的還是無符號的,其內部的二進制表示形式都是相同的。
在 Java 中,編譯器使用二進制補碼記法來表示有符號整數。因此,在上面的 示例 3 中,輸入表示有符號整數 -3。
示例 1:

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

示例 2:

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

示例 3:

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

提示:
輸入必須是長度為 32 的 二進制串 。
進階:
如果多次調用這個函數,你將如何優化你的算法?

思路及解法

循環檢查

1.循環檢查給定的整數每一位是否為1;

2.將n跟給定的對應位置上的數字進行與運算,如果兩個相應的二進制位都為1,則該位的結果值為1,結果加1,否則為0。

var hammingWeight = function (n) {
    let res = 0
    for (let i = 0; i < 32; i++) {
        //將每一位與n進行與運算,檢查是否每一位是否為1
        if ((n & (1 << i)) != 0) {
            res++
        }
    }
    return res
};

位運算

  1. n &= n - 1 實現讓最低位變為0
  2. 減少了循環的次數,記錄循環的次數
var hammingWeight = function(n) {
    let res = 0;
    while (n) {
        n &= n - 1; //將最低位變為0
        res++;  //記錄變了幾次
    }
    return res;
};
carbon(3).png

補充無符號位移 >>>

>>>運算符執行五無符號右移位運算。它把無符號的 32 位整數所有數位整體右移。對于無符號數或正數右移運算,無符號右移與有符號右移運算的結果是相同的。

console.log(1000 >> 3);  //返回值125
console.log(1000 >>> 3);  //返回值12

對于負數

console.log(-1000 >> 3);  //返回值-125
console.log(-1000 >>> 3);  //返回值536870787

對于負數來說,無符號右移將使用 0 來填充所有的空位,同時會把負數作為正數來處理,所得結果會非常大所以,使用無符號右移運算符時要特別小心,避免意外錯誤。

如圖:左側空位不再用符號位的值來填充,而是用 0 來填充。


image
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容