【问题标题】:Bit Manipulation and XOR位操作和异或
【发布时间】:2019-09-12 21:39:27
【问题描述】:

我有一个关于算法中的位操作的问题。

给定一个整数数组,数组中的每个元素都出现三次,除了一个元素只出现一次。找到只出现一次的元素。

例子:

Input : [1, 2, 4, 3, 3, 2, 2, 3, 1, 1]  
Output : 4

我遇到了使用XOR 的解决方案,但我无法理解。以下是解决方案:

int singleNumber(vector<int> A) {
    int first = 0;
    int second = 0;
    for(auto n:A){
        first = (first ^ n) & ~second;
        second = (second ^ n) & ~first;
    }
    return first;
}

有人能解释一下下面两行代码的工作原理吗?

first = (first ^ n) & ~second;
second = (second ^ n) & ~first;

[已编辑]

我为循环中的每次迭代都包含了cout&lt;&lt;first&lt;&lt;" "&lt;&lt;second&lt;&lt;endl;,但它显示了我无法理解的以下输出。这如何导致解决方案?

1 0
3 0
7 0
4 3
4 0
6 0
4 2
5 0
4 1
4 0

【问题讨论】:

  • 执行过程中的什么时候你会感到困惑?显示您打印的痕迹,或您所做的桌面检查;解释你在哪里卡住了。
  • @Prune 嗨,我已经编辑了我的问题,现在请回答。
  • 我会等待我请求的跟踪和解释。
  • @Prune 我没有被困在执行中。我被困在唯一的解释中,为什么这段代码有效?那么,我应该如何回答解释部分?
  • 查看所有循环中的值,以及每个操作的结果。向我们解释您不遵循顺序的地方。也许通过一些代数来推导出firstsecond 的新值作为n 的函数。通过一个 8 行的真值表来查看每种输入组合会发生什么。

标签: c++ algorithm xor bitmask


【解决方案1】:

这段代码的作用是计算每个位的出现次数,并行,mod 3。

first 的第 n 位和second 的第 n 位一起构成这个计数器。

看看当我将firstsecond 写在一起然后合并新数字中的一点时会发生什么。以下是所有可能性:

             secondfirst    00  01  10    00  01  10
                 new bit     0   0   0     1   1   1
first=first^new &~second     0   1   0     1   0   0
+ sec=sec^new & ~first      00  01  10    01  10  00

如您所见,当新数中的对应位为 0 时,这两个位保持不变。但是,当新位为 1 时,它们会经过一个循环,每 3 步返回到00。如果 1 的个数是 3n+1,我们在first 中剩下一个 1 位

【讨论】:

    猜你喜欢
    • 2022-11-17
    • 1970-01-01
    • 1970-01-01
    • 2022-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-27
    • 1970-01-01
    相关资源
    最近更新 更多