试图了解XOR的重要性,我找到了这段代码:
给定一组数字,其中除了一个数字之外所有元素都出现偶数次,找到奇数出现的数字
但我无法想象它。 XOR按位运算符如何推出奇数元素?
// Function to return the only odd occurring element
int findOdd(int arr[], int n) {
int res = 0, i;
for (i = 0; i < n; i++)
res ^= arr[i];
return res;
}
int main(void) {
int arr[] = { 12, 12, 14, 90, 14, 14, 14 };
int n = sizeof(arr) / sizeof(arr[0]);
printf("The odd occurring element is %d\n", findOdd(arr, n));
return 0;
}
输出:The odd occurring element is 90
答案 0 :(得分:2)
二进制XOR是异或操作,一次执行一位。它相当于减法,模2。
以下是XOR的真值表:
a b a^b
1 0 1
1 1 0
0 0 0
0 1 1
如您所见,当输入位的EITHER为1时,XOR将位设置为1(真),但不是两者都是。
现在,考虑一下:什么是1 xor 1?从真相表中,你知道它是零。
什么是1 xor 1 xor 1?好吧,你知道1 ^ 1 == 0,所以留下0 ^ 1,即1。
所以你有x或偶数次1会产生零,奇数次会产生1。
因此,如果我们取a ^ a ^ a
,对于a的某个值,我们得到一个结果,其中a的二进制表示中的所有1位都被设置。 (也就是说,我们会回来&#39; a&#39;。)
然而,如果我们取a ^ a ^ a ^ a
,对于a的某个值,我们得到一个结果,其中a的二进制表示中的所有1位都是0.(也就是说,我们得到0。)< / p>
当然,对此的一个例外是0. 0的二进制表示没有设置位,因此这种方法不会指示0的数量是偶数还是奇数。
答案 1 :(得分:1)
XOR表示异或,对于操作数中的每个位,如果操作数的相应位为1
,则结果位为1
,但不是两者:
0 ^ 0 = 0
,1 ^ 0 = 1
,1 ^ 0 = 0
和1 ^ 1 = 0
。
对于所有值,相同的数字相互取消为x ^ x == 0
。 xoring数组的所有元素的最终结果是出现奇数次数,假设只有一个。
如果所有重复的数字只出现偶数次并且只有一个条目出现奇数次,则此方法有效。
答案 2 :(得分:1)
但我无法将其可视化
然后你应该一次一行地执行代码,并在循环的每次迭代中密切关注res
。
或者只是在纸上写下来 - 记下12的二进制形式,即00001100
,然后将该值与下一个值进行异或,也是00001100
,这会让你回到{{ 1}}。然后用它对Xor表示下一个值,依此类推。您可能希望从一组简短的数字对开始,例如00000000
,看看会发生什么。然后尝试删除最后一个,这样你就可以{12, 12, 15, 15}
看看你得到了什么。然后尝试重新排序列表:{12, 12, 15}
。计算每个位翻转的次数。
答案 3 :(得分:1)
我读它的方式你真的问了两个问题:
为了理解问题(2),必须理解问题(1)。理解问题(1)需要充分介绍XOR逻辑及其所具有的属性。
XOR的重要性是什么?
定义:当且仅当TRUE输入的数量为奇数时,XOR运算的输出为TRUE。通常被称为“一个或另一个,但不是两个”
这由以下真值表捕获: XOR Truth Table
使用真值表导出以下属性是微不足道的:
现在谈谈XOR的重要性,即这些属性如何让人们做出有用的东西。要注意的第一个计算层是硬件层。 XOR门是在许多基本逻辑电路中具有实用性的物理设备,其基本效用是“奇数发生检测”。一些值得注意的应用:
除了这些电路,我们还可以在硬件级别使用XOR检查错误检测和纠正(EDAC)操作的字节奇偶校验,交换寄存器值(没有临时变量!),并从中恢复损坏/丢失的数据RAID系统中的硬盘驱动器。
然而,软件爱好者并不关心这些电路,他们希望生活在抽象的领域,提供一种以人类直观的方式使用这种硬件的简单方法。让代码。
XOR如何帮助查找系列中数字奇数?
即使对您的问题的第一条评论表明海报不理解您的问题,但他们无意中正确回答了问题,但我会进一步解释。
让我们分解你的findOdd()函数实际上在做什么。 for循环实际上执行以下计算:
结果= 0 ^ 12 ^ 12 ^ 14 ^ 90 ^ 14 ^ 14 ^ 14
回想一下,XOR是交际的,所以在稍微重新排序后,计算就变成了:
结果= 0 ^ 12 ^ 12 ^ 14 ^ 14 ^ 14 ^ 14 ^ 90
使用属性A ^ A = 0和关联性,12和12的XOR与14的XOR一样下降到0,留下:
结果= 0 ^ 0 ^ 0 ^ 0 ^ 90 = 0 ^ 90 = 90
实际上,XOR迫使偶数事件变为零,A ^ 0 = A.希望这个详细的XOR描述有助于可视化引擎盖下发生的事情。
答案 4 :(得分:0)
这都是关于XOR运算符的。
git clone
有点XOR
例如,
^
根据12^5 == 1100^0101 == (1^0)(1^1)(0^1)(0^1) == 1011
的数学定义,如果输入中XOR
(s)的数量为奇数,则输出为1
。
此案例:
当一个数字出现偶数次时,二进制表示在每个位置也会得到两个1
或两个1
,结果将转到0
。
例如:
0
请注意,即使出现的数字也没有影响。
答案 5 :(得分:0)
XOR是可交换的:a ^ b
等于b ^ a
XOR是关联的:a ^ (b ^ c)
等于(a ^ b) ^ c
。
这两个意味着你可以在一系列XOR中任意重新排序操作数。
此外:
0
是一个中性元素:a ^ 0
等于a
每个数字都是自己的倒数:a ^ a
等于0
。
在我们的代码中,我们正在进行12 ^ 12 ^ 14 ^ 90 ^ 14 ^ 14 ^ 14
。
我们可以将此重新排序为(12 ^ 12) ^ (14 ^ 14) ^ (14 ^ 14) ^ 90
,将与自身偶数次出现的每个元素配对。
这简化为0 ^ 0 ^ 0 ^ 90
(因为所有相等元素对相互抵消,给出0
),这会减少到90
(因为与0
进行异或没有)。
答案 6 :(得分:0)
鉴于以下公理:
x ^ x ^ y ^ y ^ y == y
\___/ \_______/
0 ^ y == y
然后例如:
x ^ y == y ^ x
此外:
x ^ x ^ x ^ y == x ^ y
所以操作数的顺序无关紧要。
该点是值出现的奇数个值,而偶数结果为0,值为0或0的值为该值。
因此,正如代码开头的注释所暗示的那样,只有当单个值出现奇数且所有其他值出现偶数次时,它才有效。否则,结果只是所有奇数值的xor,例如:
Class A
既不是x也不是y。