这个题如果换成数组中只出现一次的一个数字,就非常好做了,大家都知道这个题目如何做,其实数组中出现一次的数字有两个也可以使用异或的方式来处理,不过不能直接进行判断,需要分成两组,每一组含有一个只出现一次的数字,
现在问题来了?
应该如何把这两数字进行分开,而且每一个数组都要含有除了只出现一次数字其他数必须都要偶数个。
简单的说要使用那两个只出现一次的异或值,通过异或值我们能发现,在某一位上产生的1代表着这两个只出现一次的数不一样之处,我们可以使用这一位把两个数字分成两组,之后其他的数字自然就分开了。之后再分别给两个数组进行异或。之后就能求出来了。
思路给出了:
代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
using namespace std;
int main (void) {
int num;
int arr[100];
int count1 = 0, count2 = 0;
int fir[100], sec[100];
int sum;
int i;
while (scanf ("%d", &num) != EOF) {
count1 = 0, count2 = 0;
for (i = 0;i < num;i++) {
scanf ("%d", &arr[i]);
}
sum = arr[0];
for (i = 1;i < num;i++) {
sum ^= arr[i];
}
for (i = 1;i < sum;i = (i << 1)) {
if (sum & i) {
break;
}
}
sum = i;
for (i = 0;i < num;i++) {
if (arr[i] & sum) {
fir[count1++] = arr[i];
}
else {
sec[count2++] = arr[i];
}
}
sum = fir[0];
for (i = 1;i < count1;i++) {
sum ^= fir[i];
}
printf ("%d ", sum);
sum = sec[0];
for (i = 1;i < count2;i++) {
sum ^= sec[i];
}
printf ("%d\n", sum);
}
return 0;
}
上面的代码我感觉实在是太长了,难看。。。。。
下面是别人写的,短小精悍。。。自愧不如。。。
void FindTwoNotRepeatNumberInArray(int *a, int n, int *pN1, int *pN2)
{
int i, j, temp;
temp = 0;
for (i = 0; i < n; i++)
temp ^= a[i];
for (j = 0; j < sizeof(int) * 8; j++)
if (((temp >> j) & 1) == 1)
break;
*pN1 = 0, *pN2 = 0;
for (i = 0; i < n; i++)
if (((a[i] >> j) & 1) == 0)
*pN1 ^= a[i];
else
*pN2 ^= a[i];
}