如何使用xor找到重复的数字和缺失的数字?
例如:actual = [1,2,3]
input_received = [3,2,3]
。缺少的数字为1
,重复的数字为3
。我在冲浪时发现了一个非常有趣的解决方案,
int missing_and_repeating(int a[], int n, int size){
int xor =0;
int i;
int x =0 , y =0;
for(i=0; i<size; i++)
xor = xor^a[i];
for(i=1; i<=n; i++)
xor = xor^i;
// Get the rightmost bit which is set
int set_bit_no = xor & ~(xor -1);
// XOR numbers in two buckets
for(i=0; i<size; i++){
if(a[i]& set_bit_no){
x = x^a[i];
}
else
y = y^ a[i];
}
for(i=1; i<=n; i++){
if(i & set_bit_no)
x = x^i;
else
y = y^i;
}
printf("\n %d %d ", x,y );
}
'actual'数组是XORed,'input_received'数组是XORed
分配了set_bit_no
,并且根据set_bit_no
将两个数组分成两半。
再次回到我们的数组和数字从1
到N-1
和0
到size
以及两个存储桶中的XOR数字,一个存储桶包含对所有数字进行XOR运算的XOR结果给定位集和其他桶包含对给定位复位的所有数字进行异或的XOR结果。
我无法理解set_bit_no
是什么以及它们为什么要接受它,以及如何根据它来分割数组。有人请帮我一个简短的例子。
答案 0 :(得分:0)
我认为前提条件是缺少一个数组元素,而是由另一个元素的副本替换。因此,actual = {a1, a2, ..., an}
和input_received = {a2, a2,..., an}
(我们可以随时重新排列元素,以便a1
丢失并重复a2
。
因此,当你对两个数组中的所有元素进行xor时,得到xored = a1 ^ a2
。
现在我们必须将该数字分解为a1
和a2
。你取其中一个非零位(不管哪一个,最简单的方法就是在代码中完成最不重要的工作,如果a1 != a2
你总是有一个)。此位仅设置为a1
或a2
中的一个。因此,你对所有具有这一位的数字进行xor,并且它们相互消灭,只留下a1
或a2
,并且你和其他所有数字相同,所以结果将是另一个数字 - {分别为{1}}或a2
。
重要的是要注意,这个算法并不能分辨出哪些数字丢失了,哪些数字是重复的。以下代码演示了这一点:
a1
输出:
int main() {
int arr1[] = {1, 1};
missing_and_repeating(arr1, 2, 2);
int arr2[] = {2, 2};
missing_and_repeating(arr2, 2, 2);
}