我假設所需的結果是異或掩模,即。與1,其中位應該被改變和0的數字,其中他們應該被保持不變(使得a XOR amask = a'
和b XOR bmask = b'
)
只是爲了完整性,的a' | b'
結果有1個比特,其中任一個「或b」或兩者都具有1,否則爲0.
首先,絕對必要的條件是a' | b' = c
是a'和b'都沒有1位,其中c有0位。換句話說,要獲得第一個amask和bmask,可以將a和b設置爲0,其中c爲1。換句話說,要獲得第一個amask和bmask,可以採用a和b並設置每一個位爲0,其中c的二進制補碼爲0。
amask = a & (~c)
bmask = b & (~c)
現在指望有多少位AMASK和bmask爲1(或用幼稚的循環,或與許多popcount功能之一在線),和從你的k中減去它。如果k變負,則不存在解決方案(返回-1)。
第二部分要求您找到a和b均爲0但c爲1的位。把它簡稱:
temp_mask = c & ((a XOR amask) | (b XOR bmask))
temp_mask是你需要設置爲1 要麼位a或b(哪一個取決於「最小」的要求,但第一,流行數temp_mask也一樣,如果結果。比你的剩餘k大,有沒有辦法解決(返回-1)
下一步很簡單:
amask = amask | temp_mask
此前曾AMASK 1,其中c爲0,這種說法現在不會重疊任何東西。
現在,您至少有一個解決方案a' | b' = c
,即
(a XOR amask) | (b XOR bmask) = c
但是仍然可能有另一個較小的a,對吧?
這也不是很難:在(a XOR amask)
中爲1的每個位,而在(b XOR bmask)
中的0都可以「移動」,即。使其在(a XOR amask)
中爲0,在(b XOR bmask)
中爲1。結果c將是相同的,但數字值(a XOR amask)
將會更小(可能最壞的情況下它保持不變)。
temp_mask = (a XOR amask) & (~(b XOR bmask))
amask = amask XOR temp_mask
bmask = bmask XOR temp_mask
爲了實現這一點,請注意unsigned
和int大小。
全部僞代碼:
amask = a & (~c)
bmask = b & (~c)
temp_mask = c & ((a XOR amask) | (b XOR bmask))
amask = amask | temp_mask
temp_mask = (a XOR amask) & (~(b XOR bmask))
amask = amask XOR temp_mask
bmask = bmask XOR temp_mask