使用xor在数组中重复和丢失数字

时间:2015-04-14 10:56:20

标签: c arrays algorithm data-structures

如何使用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将两个数组分成两半。 再次回到我们的数组和数字从1N-10size以及两个存储桶中的XOR数字,一个存储桶包含对所有数字进行XOR运算的XOR结果给定位集和其他桶包含对给定位复位的所有数字进行异或的XOR结果。

我无法理解set_bit_no是什么以及它们为什么要接受它,以及如何根据它来分割数组。有人请帮我一个简短的例子。

1 个答案:

答案 0 :(得分:0)

我认为前提条件是缺少一个数组元素,而是由另一个元素的副本替换。因此,actual = {a1, a2, ..., an}input_received = {a2, a2,..., an}(我们可以随时重新排列元素,以便a1丢失并重复a2

因此,当你对两个数组中的所有元素进行xor时,得到xored = a1 ^ a2

现在我们必须将该数字分解为a1a2。你取其中一个非零位(不管哪一个,最简单的方法就是在代码中完成最不重要的工作,如果a1 != a2你总是有一个)。此位仅设置为a1a2中的一个。因此,你对所有具有这一位的数字进行xor,并且它们相互消灭,只留下a1a2,并且你和其他所有数字相同,所以结果将是另一个数字 - {分别为{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);
}