问题描述:
一个数组中只有两个数字是出现一次,
其他所有数字都出现了两次。
找出这两个只出现一次的数字,编程实现。
问题分析:
1、先将所有数字异或,结果为两个不一样数字异或的结果,存在 ret 里;
2、从右往左找出 ret 二进制数第一位为 1 的位置,存在 pos 里,pos位为1分一组,为0分一组;
3、通过 if (1 == ((a[i] >> pos) & 1)) 把两个不同的数分开;
4、两组分别进行异或,一组结果存在 first 里,另一组结果存在 second 里。
源代码:
#include<stdio.h>
#include<windows.h>
int find_num(int a[], int len)
{
int i = 0;
int ret = 0;//记录所有值异或的结果
int pos = 0;//记录ret二进制为第一个为1的位置
int first = 0;//将一组值异或存在first,得到1个没有相同数字的值
int second = 0;//将另一组值异或存在second,得到另1个没有相同数字的值
//先将所有数异或
for (i; i < len; i++)
{
ret ^= a[i];
}
//找到ret二进制数第一个为1的数
for (i = 0; i < 32; i++)
{
if (1 == ((ret >> i) & 1))
{
pos = i;
break;
}
}
//分组异或
for (i = 0; i < len; i++)
{
if (1 == ((a[i] >> pos) & 1))
{
first ^= a[i];
}
else
{
second ^= a[i];
}
}
printf("first = %d\nsecond = %d\n", first, second);
}
int main()
{
int arr[8] = { 1, 2, 3, 4, 3, 2, 1, 5 };
int len = sizeof(arr) / sizeof(arr[0]);
find_num(arr, len);
system("pause");
return 0;
}
代码优化:(指针)
#include<stdio.h>
#include<windows.h>
void Func(int *arr, int len, int *px, int* py)
{
int i = 0;
int num = 0;
int pos = 0;
for (i = 0; i < len; i++)
{
num ^= arr[i];
}
//整体异或的结果,存放到了num
for (i = 0; i < 32; i++)
{
if (1 == ((num >> i) & 1))
{
pos = i;
break;
}
}
//分组异或
for (i = 0; i < len; i++)
{
if (((arr[i] >> pos) & 1) == 1)
{
*px = *px^arr[i];
}
else{
*py = *py^arr[i];
}
}
}
int main()
{
int arr[] = { 1, 3, 2, 4, 1, 5, 3, 4 };
int len = sizeof(arr) / sizeof(arr[0]);
int x = 0;
int y = 0;
Func(arr, len, &x, &y);
printf("%d,%d\n", x, y);
system("pause");
return 0;
}