Ich nehme an, die gewünschten Ergebnisse sind XOR-Masken, dh. mit 1-Nummern, wo Bits geändert werden sollte, und 0, wenn sie unberührt gelassen werden soll (so daß a XOR amask = a'
und b XOR bmask = b'
)
Nur der Vollständigkeit halber, hat das Ergebnis der a' | b'
1 Bits, wobei entweder A ‚oder B‘, oder beide haben 1, sonst 0.
Da ist zuerst, unbedingt notwendig, Bedingung für a' | b' = c
ist, dass weder ein 'noch b' 1 Bits haben, wo c 0 Bits hat. Mit anderen Worten, um die erste Amask und Bmask zu erhalten, können Sie a und b nehmen und jedes Bit auf 0 setzen, wobei c 1 hat. Mit anderen Worten, um die erste Amask und Bmask zu erhalten, können Sie a und b nehmen und setzen jedes Bit auf 0, wo das binäre Komplement von c 0.
amask = a & (~c)
bmask = b & (~c)
Jetzt hat zählen, wie viele Bit sind in 1 und AMASK BMASK (entweder mit einem naiven Schleife oder mit einer der vielen Funktionen PopCount online), und subtrahiere das von deinem k. Wenn k negativ wird, gibt es keine Lösung (return -1).
Der zweite Teil erfordert, dass Sie Bits finden, wo sowohl a als auch b 0 sind, aber c ist 1.Um es kurz:
temp_mask = c & ((a XOR amask) | (b XOR bmask))
temp_mask sind die Bits müssen Sie 1 in entweder a oder b setzen (die man auf den „kleinsten“ Anforderung hängt Aber zuerst, Pop-count temp_mask auch, wenn das Ergebnis. größer ist als weitere k ist, gibt es keine Lösung ist (-1 zurück)
Der nächste Schritt ist einfach:.
amask = amask | temp_mask
Der bisherige AMASK 1 hat, wo c 0 ist, nun diese Aussage wird nichts überlappen .
Jetzt haben Sie mindestens eine Lösung für a' | b' = c
, das ist
(a XOR amask) | (b XOR bmask) = c
Aber da könnte noch eine andere mit einer kleineren a sein, oder?
Das ist auch nicht sehr schwer: Jedes Bit, das 1 in (a XOR amask)
ist, aber 0 in (b XOR bmask)
kann "bewegt" werden, dh. mach es 0 in (a XOR amask)
und 1 in (b XOR bmask)
. Das Ergebnis c wird gleich sein, aber der numerische Wert von (a XOR amask)
wird kleiner sein (möglicherweise bleibt er im schlimmsten Fall gleich).
temp_mask = (a XOR amask) & (~(b XOR bmask))
amask = amask XOR temp_mask
bmask = bmask XOR temp_mask
Um dies zu implementieren, achten Sie auf unsigned
und Int-Größen.
Voll Pseudo-Code:
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