[英]Counting the number of solutions for 2 related equations
我如何找到解决方案的数量
s = a+b
x = a^b
当给出s
和x
, ^
表示xor
?
那么对于喜欢(0,0)
或(31,31)
或(15,10)
?
我已经尝试将x
转换为二进制字符串,但之后我不确定将它放在哪里。
如果没有解决方案,方法solution
将返回null
。 如果有解决方案,则返回a
(仅针对一个解决方案)。 你可以通过做s - a
或x ^ a
得到b
。
如果存在解决方案,则解决方案的总数(以long
)是Long.bitCount(x)
的幂的2。
例如,对于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
,因为在某些情况下,这些集合会很大。 但是,您可以编写一种方法来生成所有可能的解决方案,而无需将它们全部存储在内存中。 例如,参见基于模式生成所有二进制数
让我们用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)
同时具有a + b和a ^ b,您可以确定进位的位c_j,从中您应该能够推导出每个a_j,b_j的解的数量的公式,具体取决于c_j和c_的值(j- 1)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.