找 单身狗(异或的运用)(找数组中只出现一次的两个元素)

一个数组中只有两个数字是出现一次,其他所有数字都出现了两次。

编写一个函数找出这两个只出现一次的数字。

例如:

有数组的元素是:1,2,3,4,5,1,2,3,4,6

只有5和6只出现1次,要找出5和6.

 要找到只出现过一次的数字,可以利用异或的性质,(同则零不同则一),所以两个相同的数字进行异或就获得到全零,零异或上一个数结果就等于这个数。,所以先把数组元素都进行异或(异或具有交换律)得到的结果等于数组中那两个数字异或

#include <stdio.h>

void findSingleNumbers(int arr[], int n) {
    int xorResult = 0;
    for (int i = 0; i < n; i++) {
        xorResult ^= arr[i];
    }

    // 找到异或结果中第一个为1的位数
    int rightmostSetBit = xorResult & -xorResult;

    int num1 = 0, num2 = 0;
    for (int i = 0; i < n; i++) {
        if (arr[i] & rightmostSetBit) {
            num1 ^= arr[i];
        }
        else {
            num2 ^= arr[i];
        }
    }

    printf("只出现一次的数字是:%d 和 %d\n", num1, num2);
}

int main() {
    int arr[] = { 1, 2, 3, 4, 5, 1, 2, 3, 4, 6 };
    int n = sizeof(arr) / sizeof(arr[0]);

    findSingleNumbers(arr, n);

    return 0;
}

,所以这个结果的二进制中的1 就是说明在这位上这两个数是不同的(有分歧的),我们需要找到任意有分歧的一位就可以把二者找出来,接下来就是要找到一位分歧位并记录他是第几位二进制位

就如同代码中的  int rightmostSetBit = xorResult & -xorResult;

首先,xorResult是一个整数,我们假设它的二进制表示形式为 xxxxxxxx...xxx1xxx...xxx,其中 x 可以是0或1。

-xorResult 是将 xorResult 的二进制表示形式取反,并加1。这可以通过以下步骤实现:

  1. 求 xorResult 的二进制补码(将 0 变为 1,将 1 变为 0)。
  2. 加上1。

例如,如果 xorResult 的二进制表示为 10111010,则 -xorResult 的二进制表示为 01000110

按位与(&)操作将 xorResult-xorResult 进行按位运算。这将导致所有位都被清除,除了最右边的设置位。因为在 -xorResult 中,只有最右边的设置位和 xorResult 相同位置的设置位为1,其他位都为0。

因此,通过执行 xorResult & -xorResult,我们得到的结果是一个整数,它只有最右边的设置位为1,其他位都为0。这将帮助我们识别最右边的设置位在哪个位置。

然后就用每个数组元素与上这个只有在分歧位是一的数,这就把数分为两类了,一个是结果为0,一个结果为1,然后设置两个接受的值赋为零(在此利用0异或为本身的性质)然后相同的数再次异或为零,最后这两个数中剩下的就是我们要的“单身狗”了

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值