鉴于[1,1,4,5,5,6]
,我们可以将4
和6
视为非重复整数。
XOR
使用#include <stdio.h>
#include <stdlib.h>
/* This finction sets the values of *x and *y to nonr-epeating
elements in an array arr[] of size n*/
void get2NonRepeatingNos(int arr[], int n, int *x, int *y)
{
int xor = arr[0]; /* Will hold xor of all elements */
int set_bit_no; /* Will have only single set bit of xor */
int i;
*x = 0;
*y = 0;
/* Get the xor of all elements */
for(i = 1; i < n; i++)
xor ^= arr[i];
/* Get the rightmost set bit in set_bit_no */
set_bit_no = xor & ~(xor-1);
/* Now divide elements in two sets by comparing rightmost set
bit of xor with bit at same position in each element. */
for(i = 0; i < n; i++)
{
if(arr[i] & set_bit_no)
*x = *x ^ arr[i]; /*XOR of first set */
else
*y = *y ^ arr[i]; /*XOR of second set*/
}
}
。
以下是作者提出的算法:
4^6
我对set_bit_no
之后的内容感到困惑。我很困惑{{1}}如何运作(包括动机)以及之后的任何事情。
有人可以尝试以更简单的英语方式解释它吗?感谢。
答案 0 :(得分:20)
如果我们有重复的数字对,它们不会向xor结果添加任何内容,因为它们的xor将为零。只有一对不同的数字会将非零位添加到xor结果中。
a xor a = 0
[a, b, c, b, d, a]
a xor b xor c xor b xor d xor a = c xor d
现在在c x或d中,唯一的设置位是c和d中不同的位。 我们说第3位是在c xor d中设置的。这意味着如果c中第3位为0,则d中为1,反之亦然。
因此,如果我们将所有数字分成2组,则包含所有数字的第3位为0,而其他第3位为1,则c和d肯定会转到不同的组。并且所有相同数字对将成为同一组。 (位3在a和0都是1)
让我们说这些小组是
[a c a] and [b d b]
xoring them
a xor c xor a = c (The first number)
b xor d xor b = d (The second number)
群体的其他可能性
[c] and [a b d b a]
xoring them
c = c (The first number)
a xor b xor d xor b xor a = d (The second number)
和
[a b c b a] and [d]
xoring them
a xor b xor c xor b xor a= c (The first number)
d = d (The second number)
关于
set_bit_no = xor & ~(xor-1);
如果输入数组由自然数组成,则xor为正数 xor&amp; ~xor为零(定义为所有位都被反转) 从xor减去1,
简而言之,1的所有最右边的位将变为零(倒退,类似于xor),第一个(最右边)的零位将变为1(与xor相同)。现在开始,这个新设置的1位的所有位在xor和〜(xor-1)中都是不同的,所以它们将生成0,所有新设置的1位都在xor和〜(xor- 1)因此它们将产生0.在两种情况下,只有位于〜(xor-1)中新设置1的位的位是1,因此在表达式xor&amp;中只设置该位。 〜(XOR-1)
答案 1 :(得分:2)
这里解释的简单方法是,当你执行a^b
时,只设置那些在b中具有不同值的位位置。因此,如果您将数组中的元素与a^b
中特定设置位的值进行分组,那么a和b将在不同的组中作为xor,组将取消其他组,两个组的结果将为a和b。< / p>
示例: -
a = 4
b = 6
a^b = 2
Set_bit_pos = 1
Arr = [1,1,4,5,5,6]
Grouping according to bit no 1
x = [6] where bit1 is 1
y = [4,1,1,5,5] where bit1 is 0
Xoring
x = 6
y = 4^1^1^5^5 = 4
答案 2 :(得分:2)
此算法仅在
时才有效1) elements are non-zero
2) contains no more than 2 non-repeating integers. If only 1
non-repeating, one of the result (x or y) will be 0.
3) the repeated numbers occurs in pairs (ie. 2,4,6....)
如果0
是可能的数字,那么您就无法区分找到的答案或没有答案。
通过对所有元素进行异或运算,可以得出2个非重复整数之间的差异(即示例中为4 ^ 6)。这是因为所有其他元素都会重复(即偶数次),而在XOR中,它们会自行取消。重要的是要注意XOR是可交换的(即,顺序并不重要^ b = b ^ a)
现在是set_bit_no
。这只是存储最右边的设置位或xor
。为什么最合适?因为我猜很容易。但是任何一点都行。 xor
变量中的设置位包含4到6之间不同的位。
100 ^ 110 = 010
第二位是1,因为4和6之间的唯一位不同。同样,3和8之间的差异
0011 ^ 1000 = 1011
表示第4位,第2位和第1位在3和8之间不同。
获取设置位并在if
条件下使用它的原因是为了确保将答案(4和6)写入不同的变量(x或y)。为什么这样做?因为set bit
保证2个答案在该位位置包含不同的值。
if(arr[i] & set_bit_no)
答案 3 :(得分:0)
当xor两个相等的值时,它们会取消。这允许揭示非重复对。
XOR(aabbccddeeffgh) = XOR(gh) = ...1...
了解g
和h
不同的任何位允许在两个子集中设置g
和h
:
...0... => XOR(aabbcceeg) = g
...1... => XOR(ddffh) = h