XOR编程拼图建议

时间:2017-01-10 16:01:03

标签: c++ xor bits

给定long int x ,计算满足以下条件的 a 的值的数量:

a XOR x > x
0< a < X

其中 a x 是长整数, XOR 是按位XOR运算符

你将如何解决这个问题?

我还应该提到输入x可以大到10 ^ 10

我设法通过迭代0到x检查条件并递增计数值来获得强力解决方案..但这不是最佳解决方案......


这是我试过的蛮力。它可以工作,但对于大的x值来说非常慢。

 for(int i =0; i < x; i++)
 {
      if((0 < i && i < x) && (i ^ x) > x)
          count++;    
 }

2 个答案:

答案 0 :(得分:4)

long long NumberOfA(long long x)
{
    long long t = x <<1;
    while(t^(t&-t)) t ^= (t&-t);
    return t-++x;
}


long long x = 10000000000;
printf("%lld ==> %lld\n", 10LL, NumberOfA(10LL) ); 
printf("%lld ==> %lld\n", x, NumberOfA(x) ); 

<强> 输出

10 ==> 5
10000000000 ==> 7179869183

Link to IDEOne Code

尝试解释逻辑(使用示例10或1010b

  • 向左移动x 1.(值20或10100b
  • 关闭所有低位,只保留高位(值16或10000b
  • 减去x + 1(16 - 11 == 5

<小时/> 试图解释
(虽然不容易)

您的规则是a ^ x必须大于x,但您无法将额外位添加到ax
(如果从4位值开始,则只能使用4位)

N位数字的最大可能值是2^n -1 (例如,4位数,2 ^ 4-1 == 15)
让我们拨打这个号码 B

在您的值x B (含)之间,有 B - x个可能值。
(回到我的示例,10。在15到10之间,有5个可能的值:11121314,{{1} })

在我的代码中,15t,然后关闭所有低位 x << 110 << 1;关闭所有低位以获取20

然后16 B B - x就是您的回答:
16 - 1t - 1 - x,相同,是答案)

答案 1 :(得分:4)

考虑这一点的一种方法是考虑 x 中的每个位。

  • 如果是1,则翻转它会产生较小的数字。
  • 如果它为0,那么翻转它将产生一个更大的数字,我们应该计算它 - 以及右边的所有位组合。这很方便地增加了掩码值。
long f(long const x)
{
    // only positive x can have non-zero result
    if (x <= 0) return 0;

    long count = 0;

    // Iterate from LSB to MSB
    for (long mask = 1;  mask < x;  mask <<= 1)
        count += x & mask
            ? 0
            : mask;

    return count;
}

我们可能怀疑这里有一个模式 - 看起来我们只是复制 x 并翻转其位。

让我们确认一下,使用最小的测试程序:

#include <cstdlib>
#include <iostream>

int main(int, char **argv)
{
    while (*++argv)
        std::cout << *argv << " -> " << f(std::atol(*argv)) << std::endl;
}
0 -> 0
1 -> 0
2 -> 1
3 -> 0
4 -> 3
5 -> 2
6 -> 1
7 -> 0
8 -> 7
9 -> 6
10 -> 5
11 -> 4
12 -> 3
13 -> 2
14 -> 1
15 -> 0

所以我们所要做的就是'涂抹'这个值,以便设置最重要的1之后的所有零位,然后xor:

long f(long const x)
{
    if (x <= 0) return 0;
    long mask = x;
    while (mask & (mask+1))
        mask |= mask+1;
    return mask ^ x;
}

这要快得多,而且还是O(log n)。