找出一个只出现过一次的数字的问题处理方法就是找一个数字把里面所有的数字都异或一遍,利用异或两次等于没异或的特点来处理。那么如果有两个数字都只出现了一次,那么如此得到的应该是两个数异或的结果。首先这个结果肯定不是0(要不然就全都配对了),所以里面一定至少一位是一。找出值为1的一位,以这一位的值将结果分为两组。例如1 2 3 4 1 2,异或完的结果应该是3^4得到的111,那么随便找一位就行了。例如找最低位,那么这一位是1的有1 3 1,是0的有2 4 2,由于是利用异或结果为1的某一位分的组,所以两个待查询数字一定分别在两组中。所以再找两个变量,分别异或两组数,即可找到这两个数。
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#define SZ 10 //总数
#define S1 39 //单身数1
#define S2 -22 //单身数2
int main()
{
int arr[SZ] = { -52, 36 ,85, S1, S2, 10, -52, 85, 10, 36 };
int n = 0; //存放两个单独的数异或的结果
int pos = 0; //n的比特位中第一次出现1的位置
int s1 = 0; //第1个单独数
int s2 = 0; //第2个单独数
for (int i = 0; i < SZ; i++)
{
n ^= arr[i];
}
for (int pos = 0; pos < 32; pos++) //两个单身数拆开
{
if ((n >> pos) & 1 == 1)
{
break;
}
}
for (int i = 0; i < SZ; i++) //分别寻找两个单身数
{
if ((arr[i] >> pos) & 1 == 1)
{
s1 ^= arr[i];
}
else
{
s2 ^= arr[i];
}
}
printf("单身数为%d %d\n", s1, s2);
system("pause");
return 0;
}