此题知识: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;
}