繁体   English   中英

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

[英]Counting the number of solutions for 2 related equations

我如何找到解决方案的数量

s = a+b
x = a^b

当给出sx^表示xor

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

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

如果没有解决方案,方法solution将返回null 如果有解决方案,则返回a (仅针对一个解决方案)。 你可以通过做s - ax ^ a得到b

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

例如,对于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 ,因为在某些情况下,这些集合会很大。 但是,您可以编写一种方法来生成所有可能的解决方案,而无需将它们全部存储在内存中。 例如,参见基于模式生成所有二进制数

让我们用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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM