找单身狗1
一个数组中只有一个数字是出现一次,其他所有数字都出现了两次。
编写一个函数找出这两个只出现一次的数字。
例如:
有数组的元素是:1,2,3,4,5,1,2,3,4
只有5只出现1次,要找出5.
异或法
异或:相同为0,相异为1
比如1^2=0,2^3=0;
a^a=0; 0^a=a
异或满足交换律,如:3^4^5=3^5^4
int find_single_dog1(int arr[], int sz) { int i = 0; int ret = 0; for (i = 0; i < sz; i++) { ret ^= arr[i];//ret=1^2^3^4^7^1^2^3^4=7 } return ret; } int main() { int arr[] = { 1,2,3,4,7,1,2,3,4 }; int sz = sizeof(arr) / sizeof(arr[0]); int dog = find_single_dog1(arr, sz); printf("%d\n", dog); return 0; }
找单身狗2
一个数组中只有两个数字是出现一次,其他所有数字都出现了两次。
编写一个函数找出这两个只出现一次的数字。
例如:
有数组的元素是:1,2,3,4,5,1,2,3,4,6
只有5和6只出现1次,要找出5和6.
思路:
将所有数组异或到一起
int i = 0; int ret = 0; for (i = 0; i < sz; i++) { ret ^= arr[i]; }
ret=5^6=3
5的二进制表示为101
6的二进制表示为110
每一位异或得011即3
计算ret的第几位是1,
int pos = 0; for (i = 0; i < 32; i++) { if (((ret >> i) & 1) == 1) { pos = i; break; } }
计算数组中元素的第pos为1的异或
for (i = 0; i < sz; i++) { if (((arr[i] >> pos) & 1) == 1) { *dog1 ^= arr[i]; } }
完整代码
#include<stdio.h> void search_dog(int arr[], int sz,int* dog1,int* dog2) { int i = 0; int ret = 0; for (i = 0; i < sz; i++) { ret ^= arr[i]; } int pos = 0; for (i = 0; i < 32; i++) { if ((ret >> i) & 1 == 1) { pos = i; break; } } for (i = 0; i < sz; i++) { if ((arr[i] >> pos) & 1 == 1) { *dog1 ^= arr[i]; } } *dog2 = *dog1 ^ ret; } int main() { int arr[] = { 1,2,3,4,5,1,2,3,4,6 }; int dog1 = 0; int dog2 = 0; int sz = sizeof(arr) / sizeof(arr[0]); search_dog(arr, sz, &dog1, &dog2); printf("%d %d", dog1, dog2); return 0; }