#include <stdio.h>
#include <windows.h>
void findNumber( int a[] , int len){
int num = 0;
int pos = 0;
int x = 0;
int y = 0;
int i = 0;
// 通过异或 求出两个只出现一次的数组元素的 异或的结果
for (; i < len; i++){
num = num ^ a[i];
}
// 查找异或结果,二进制第一次出现 1 的位置,
// 因为两个只出现一次的数组元素时一定不痛的,所以,异或的二进制结果一定含有 1,
// 通过与1按位& ,求出第一个含有 1 的位置,若没找到,则通过 >> 向右移位的方式 找,找到后,就直接跳出循环。
for (i = 0; i < 32; i++){
if (1 == ( (num >> i)& 1 ) ) {
pos = i;
break;
}
}
// 通过所找到的 第一次出现 1的位置pos,对每个数组元素向右移位,
// 将所有数组元素该位置的二进制数 与 1 相与 ( & ) , 将数组分为两部分
// 1. 数组元素二进制在该位 为 1 ; 2. 数组元素二进制在该位 为 0;
// 由于pos记录的是 两个只出现一次的数组元素的 异或的结果二进制 第一次出现1的位置,
// 在此位置,两个单一数组元素 ,一定 一个为 0 ,一个为 1;
// 因此通过此操作,两个单一数组元素,一定被分开了,
// 此时 分别进行异或操作。得出两个只出现一次数组元素的 值。
for ( i = 0; i < len;i++){
if (1 ==(( a[i] >> pos )& 1 )){
x ^= a[i];
}
else{
y ^= a[i];
}
}
printf("%d %d", x,y);
}
int main()
{
int arr[] = { 7, 2, 3, 2, 5, 4, 3, 4 };
int len = sizeof(arr) / sizeof(arr[0]);
findNumber(arr, len);
system("pause");
}