簡體   English   中英

在此算法中如何反復清除最低有效位?

[英]How does clearing least significant bit repeatedly work in this algorithm?

以下 function 確定了將 integer A 轉換為 integer B 所需翻轉的位數。 它顯然有效,但我的問題是為什么?

def bit_swap_required(a: int, b: int) -> int:
    count, c = 0, a ^ b
    while c:
        count, c = count + 1, c & (c - 1)
    return count

我明白我們為什么要做a^b 它在我們需要翻轉的每個地方都給了我們一個“1”。 但是,如何做c & (c-1)反復給你數字中“1”的確切數量?

c - 1取消設置c二進制表示中的最低有效位並將所有未設置的位設置到該位的右側。

當您二進制和c - 1c您有效地取消設置最低有效設置位右側的所有位以及最低有效設置位。 換句話說, c中的最低有效設置位及其右側的所有內容都變為零。

你把它算作一個,這是正確的。 因為它只是a ^ b一組位。

現在,您繼續此操作,直到c變為零,操作數是c中設置的位數,即ab之間的不同位數。

舉例說明c - 1c的二進制表示的作用:

c = 6, in binary 110
c-1 = 5, in binary 101
(c-1) & (c) = 110 & 101 = 100
The above is one iteration of the loop

Next iteration
c = 4, in binary 100
c-1 = 3, in binary 011
(c-1) & (c) = 100 & 101 = 0

以上成功統計了6中設置的位數。

與在每次迭代時右移數字並檢查是否設置了最低有效位相比,此優化可幫助您改進算法。 在前一種情況下,您在最高有效設置位所在的位置數進行操作。 假設 2 的冪,2^7,你迭代 8 次,直到數字變為零。 使用優化的方法時,您可以根據設置的位數進行迭代。 對於 2^7 來說,這只是一次迭代。

從代碼的結構,你可以猜到c & (c-1)c少一個1 ,即使沒有研究表達式

實際上,減去1會從右邊翻轉所有0位(有借位),直到最右邊的1包含在內。 因此,如果您bitwise and使用c ,則只有最右邊的1消失。

例如 c = 1001010 100 -> c-1 = 1001010 011 -> c & (c-1) = 1001010 0 00。

接下來,c = 10010 10000 -> c-1 = 10010 01111 -> c & (c-1) = 10010 0 0000。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM