邏輯位運算符
位運算就是對二進制數執行計算,是整數的逐位運算。
圖片.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
};
位運算
- n &= n - 1 實現讓最低位變為0
- 減少了循環的次數,記錄循環的次數
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