计算2个相关方程的解的数量

时间:2015-04-12 16:34:18

标签: java algorithm math xor

如何找到

的解决方案数量
s = a+b
x = a^b

提供sx时,^表示xor

那么对于(0,0)(31,31)(15,10)

我已尝试将x转换为二进制字符串但在此之后我不确定将其放在哪里。

2 个答案:

答案 0 :(得分:4)

如果没有解决方案,方法solution会返回null。如果有解决方案,则返回a(仅针对一个解决方案)。您可以通过bs - a获得x ^ a

如果存在解决方案,则解决方案的总数(long)为Long.bitCount(x)的幂。

例如,找到s = 24x = 6的解决方案是a = 9b = 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)。