题目:一个数组中只有两个数字是出现一次,其他所有数字都出现了两次,找出这两个只出现一次的数字。
例:有数组arr[]={1,2,3,4,5,3,2,1},输出4,5
通过题目可以达成的共识有:
- 一定有偶数个数字,且仅有两个数不同其它数成对出现
- 整体异或,结果一定是那两个不同数的异或结果。0^任何数->任何数;两个相同的数异或结果为0
- 两个不同的数异或结果,一定不为0,将其视作二进制,一定有至少一位为1,该位置上两个数一个为0,一个为1
- 用该比特位的不同将数分为两组,每一组都有成对的数和一个单独的数
- 组内元素异或完成后,剩下单独的数
代码如下:
#include<stdio.h>
#include<windows.h>
int FindDate(int arr[], int num, int *x, int *y)
{
int falg = 0;
int data = 1;
int i = 0;
for (i = 0; i < num; i++){
falg ^= arr[i];
}
for (i = 0; i < 32; i++){
if (falg & (data << i)){
break;
}
}
data <<= i;
for (i = 0; i < num; i++){
if (arr[i] & data)
*x ^= arr[i];
else
*y ^= arr[i];
}
return 0;
}
int main()
{
int x = 0, y = 0;
int arr[50] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 23, 56 };
int num = sizeof(arr) / sizeof(arr[0]);
if (0 == FindDate(arr, num, &x, &y)){
printf("%d,%d\n", x, y);
}
system("pause");
}
程序运行结果: