此题知识:a^0=a;a^a=0;传值调用和传址调用要分清作用
题目:在 1,2,3,4,5,6,1,3,4,5这几个数字中找出只出现一次的数字并打印在屏幕上
解题思路:先将所有数字异或起来,得到一个数字tmp,此题中tmp=00.....0011(2进制);
然后找到最右边第一个为一的位数用k去存放起来;这样就能将2和6分开起来,这里是解题的关键。
再然后遍历数组,将k位(二进制)为1的异或起来,不为1的异或起来存放两个变量中然后打印在屏幕上,本题中多次利用a^0=a;a^a=0;
void FindNum(int* arr, int n, int* pnum1, int* pnum2)//传址调用
{
int tmp = 0;
for (int i = 0; i < n; i++)
{
tmp ^= arr[i];
}
int k = 0;
for (int i = 0; i < 32; i++)
{
if (((tmp >> i) & 1) != 0)
{
k = i;
break;
}
}
*pnum1 = *pnum2 = 0;
for (int i = 0; i < n; i++)
{
if (((arr[i] >> k) & 1) != 0)
{
*pnum1 ^= arr[i];
}
else *pnum2 ^= arr[i];
}
}
int main()
{
int arr[] = { 1,2,3,4,5,6,1,3,4,5 };
int n = sizeof(arr) / sizeof(arr[0]);
int num1 = 0, num2 = 0;
FindNum(arr, n, &num1, &num2);
printf("%d %d", num1, num2);
return 0;
}