【问题标题】:How to take the xor of the numbers from 1..n, for a given n? (eg 1^2^3^...^n)?对于给定的 n,如何从 1..n 中取数字的异或? (例如 1^2^3^...^n)?
【发布时间】:2015-11-14 06:28:06
【问题描述】:

这是我遇到的一个面试问题,我知道如何通过反复异或数字来获得暴力解决方案,但我不知道如何更有效地做到这一点。

我在careercup上看到了这个解决方案:

typedef unsigned long long UINT64;

UINT64 getXOROne2N(UINT64 n) {
    switch (n % 4) {
        case 0: return n;
        case 1: return 1;
        case 2: return n + 1;
        case 3: return 0;
    }
    return 0;
}

但是即使有那个家伙的解释我也不完全理解这里的逻辑,有人可以解释一下如何做到这一点吗?

【问题讨论】:

  • 这里面有什么不明白的地方?
  • 给了here的正确解释。
  • 困难的部分似乎是高位,n 显示所有其他结果提供线索。

标签: algorithm bit-manipulation xor bitwise-xor


【解决方案1】:

当您查看n 的升序值的答案时,会出现一种数学模式。它看起来像一个有四个步骤的旋转。这是因为我们在将奇数和偶数异或成先前偶数和奇数结果的各种组合之间来回摆动。每个连续的 xor 都会给我们带来四分之一的旋转。我会演示和解释。

让我们逐案检查,从头开始,n=1

00000001

请注意,这在解中的case 1 范围内,返回的结果为1。还要注意n 的这个值是奇数,因此它必然以1 结尾。

现在,当我们计算n=2 的解时,它将是先前答案的解与n 的新值异或:

00000001
       ^
00000010
--------
00000011

请注意,这属于解决方案的case 2,其中返回的结果是n + 1。还要注意,在这种情况下n 是偶数,必然以0 结尾——所以当异或到之前的结果 1(奇数)时,我们只会翻转额外的位,因此任何类似情况下的结果都会同样永远是n+1

对于下一个值,getXOROne2N(3) 的结果自然是上一个结果,经过3 异或。有趣的是,这将我们清零:

00000011
       ^
00000011
--------
00000000

当我们考虑它时,这是有道理的; getXOROne2N(2) 的结果是 n+1 = 2+1 = 3,所以当我们异或到下一个值沿 (n+1) 时,这将取消所有有符号位恢复为 0。另请注意,这属于 case 3 in您提出的解决方案。

现在,每当我们在得到 0 之后计算下一个 getXOROne2N 值时,它就只是 n 的下一个值——所以 getXOROne2N(4) 是 4。

00000000
       ^
00000100
--------
00000100

请注意,这完全属于您提供的解决方案中的case 0

现在,因为4 与前一个结果 0 异或是偶数,所以结果必然有一个尾随 0。因此,与折叠异或的行中的下一个值 5 必须具有这个先前的位配置,但具有最后一位设置为 1,这意味着当我们将其与上一个结果进行异或运算以计算 getXOROne2N(5) 时,我们将取消除最后一位之外的所有内容并返回 1:

00000100
       ^
00000101
--------
00000001

因此我们形成了我们的轮换。这之后的下一个将异或一个偶数并因此产生n+1(奇数),然后下一个将取消回0(异或奇数产生这个偶数结果),然后我们'将得到下一个n(必须是偶数),因此在随后的奇数下一个值中进行异或运算将抵消除最后一个保持打开的所有位之外的所有位,再次产生 1。

这是一个恶性循环!但我认为相当整洁。

【讨论】:

    【解决方案2】:

    首先要注意的是,从可被 4 整除的数字开始的连续 4 个数字如果异或,则结果为 0:

        ...00 - starting with any binary digits
        ...01
        ...10
        ...11
    XOR -----
            0 : 4 times (...), twice 1 for both lower digits
    

    这实际上意味着只有在 n 之前最大可被 4 整除后的最后一个数字才能形成实际结果(您可以将之前的所有数字分组为四边形,每个数字都为 0)。

    所以,它来了

    %4    n               calc           result
    0   ...00  ->  ...00 =               n
    1   ...01  ->  ...00 XOR ...01 =     1
    2   ...10  ->  ...10 XOR 1 = ...11 = n + 1
    3   ...11  ->  ...11 XOR ...11 =     0
    

    【讨论】:

      猜你喜欢
      • 2012-07-30
      • 2011-01-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-06-17
      • 1970-01-01
      • 1970-01-01
      • 2021-12-30
      相关资源
      最近更新 更多