这道题根据异或运算的性质:任何数和自己异或都等于0。
用0依次和数组中的每个元素进行异或,出现两次的数字通过异或会相互抵消,最后剩下的就是只出现一次的数字。剩下的两个数不相等,异或的话至少有一位是为1的,二进制对应位也不相同。
1.得到0与数组中各元素依次异或的结果;
2.找到依次异或后的结果中为1的位置并标记,根据标记位是否为1进行分组;
2.将原数组分为两组,每组都含有一个只出现一次的数字,然后进行数组元素依次异或, 剩下的即为出现一次的数字。
int Num_Finding(int arr[], int size, int *num1, int *num2)
{
int i = 0;
int tmp = 0;
int flag = 0;
for (i = 0; i < size; i++)
{
tmp ^= arr[i];
}
//找到异或结果数第一个不为零的位,以这个条件对数组中的元素进行分类
for (i = 0; i < 32; i++)
{
if (((tmp >> i) & 1 )!= 1)
{
flag++;//用flag标记为1的位置
}
else
{
break;
}
}
for (i = 0; i < size; i++)
{
//二进制位第一位不为零的数
if (((arr[i] >> flag) & 1 )!= 1)
{
*num1 ^= arr[i];
}
else
//二进制位第一位为零的数
{
*num2 = tmp^(*num1);
}
}
return *num1, *num2;
}
int main()
{
int num1 = 0;
int num2 = 0;
int arr[] = { 1, 3, 4, 2, 4, 3 };
int size = sizeof(arr) / sizeof(arr[0]);
Num_Finding(arr, size, &num1, &num2);//需要对num1,num2返回所以这里选择传地址
printf("%d %d\n", num1, num2);
return 0;
}