如何找到
的解决方案数量s = a+b
x = a^b
提供s
和x
时,^
表示xor
?
那么对于(0,0)
或(31,31)
或(15,10)
?
我已尝试将x
转换为二进制字符串但在此之后我不确定将其放在哪里。
答案 0 :(得分:4)
如果没有解决方案,方法solution
会返回null
。如果有解决方案,则返回a
(仅针对一个解决方案)。您可以通过b
或s - a
获得x ^ a
。
如果存在解决方案,则解决方案的总数(long
)为Long.bitCount(x)
的幂。
例如,找到s = 24
,x = 6
的解决方案是a = 9
,b = 15
。
二进制:
9 = 1001
15 = 1111
这些数字在2个位置上有所不同,因此总共有Math.pow(2, 2) = 4
个解决方案。您可以通过将a
的位与b
的相应位替换为部分或全部位置来获得所有可能的解决方案。
这提供了3个进一步的解决方案。
11 = 1011 13 = 1101 15 = 1111
13 = 1101 11 = 1011 9 = 1001
以下是代码:
public static Long solution(long s, long x) {
return recursive(s, x, false);
}
private static Long recursive(long s, long x, boolean carry) {
boolean s1 = (s & 1) == 1;
boolean x1 = (x & 1) == 1;
if ((s1 == x1) == carry)
return null;
if ((s == 0 || s == -1) && (x == 0 || x == -1))
return s;
Long a;
if (x1)
return (a = recursive(s >> 1, x >> 1, carry)) == null ? null : a << 1;
if ((a = recursive(s >> 1, x >> 1, false)) != null)
return a << 1;
if ((a = recursive(s >> 1, x >> 1, true)) != null)
return 1 + (a << 1);
return null;
}
我决定不写一个方法来返回所有解决方案的HashSet
,因为在某些情况下,这些集合会很大。但是,您可以编写一种方法来生成所有可能的解决方案,而无需将它们全部存储在内存中。例如,请参阅Generating all binary numbers based on the pattern
答案 1 :(得分:2)
让v_j表示值v的第j位,其中j = 0是最低有效位。
关键观察是算术和a + b可以用xor运算a ^ b和加法的进位表示。 我们有
s_j = a_j ^ b_j ^ c_j = x ^ c_j
其中c_j是添加到第j个位置的进位。 要弄清楚进位是怎么回事,请注意
c_0 = 0
c_1 = a_0 & b_0 (so c_1 is one when both a_0 and b_0 are one)
c_j = 1 if and only if at least two of a_j, b_j, c_(j-1) are one.
最后一个条件基本上就是说
c_j = Majority(a_j, b_j, c_(j-1)) = a_j & b_j ^ a_j & c_(j-1) ^ b_j & c_(j-1)
同时具有+ b和a ^ b,您可以确定进位的位c_j,并且您应该能够根据c_j和c_的值推导出每个a_j,b_j的解的数量的公式。 (J-1)。