#define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> #include<stdlib.h> int main() { int ascii[255] = { 0 }; int arr[] = { 1, 9, 1, 2, 3, 4, 4, 9}; int len = sizeof(arr) / sizeof(arr[0]); int i = 0; for (i = 0; i < len; i++) { ascii[arr[i]] ++; } for (i = 0; i < len; i++) { if (ascii[arr[i]] == 1) { printf("%d ", arr[i]); } } system("pause"); return 0; }
另外,经过学习,第一种方法很容易想到,第二种方法经典不易想到,现附加方法2.
思路:将数组所有元素均异或,可用来解决“一组数,仅有一个数单独存在,其余数都是成对出现的,找出这个数”这个问题。
因此,将数组所有元素均异或得tmp,找出tmp从左往右或从右往左(我采用从右往左)起最开始哪一位最先出现二进制1.存下该位pos.然后根据该位是否为1将数组可分为2组。同组内相互异或可分别得到这两个数num1,num2.
全部异或为7(即111) pos = 1
1:0001 pos = 1, A组
1:0001 pos = 1, A组
2:0010 pos != 1, B组
2:0010 pos != 1, B组
3:0011 pos = 1, A组
4:0100 pos != 1, B组
A组元素全部异或得到num1 = 3,
B组元素全部异或得到num2 = 4
代码如下:
#define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> #include<stdlib.h> #include<assert.h> int tmp_bit(int num) { int count = 0; while (num) { //使用计数器找到传过来的tmp从右往左起第一次出现1的位数 if ((num & 1) == 1) return count; count++; num = num >> 1; } return -1;//考虑num为负数情况 } void find_num(int arr[], int len, int *p1, int *p2) { int i = 0; int tmp = 0; int pos = 0; //遍历整个数组全部进行异或运算,tmp得到整个数组异或的结果.注意将tmp初始附成0. for (i = 0; i < len; i++) { tmp ^= arr[i]; } pos = tmp_bit(tmp); //pos接收count的值 //现将数组分组,pos位为1与pos不为1 for (i = 0; i < len; i++) { if (1 & (arr[i] >> pos)) //pos位为1的每次异或运算,得到一个单独的数 *p1 ^= arr[i]; else *p2 ^= arr[i]; //pos位不为1的每次异或运算,得到另外一个单独的数 } } int main() { int arr[] = { 1, 3, 1, 3, 5, 7, 9, 5 }; int len = sizeof(arr) / sizeof(arr[0]); int num1 = 0; int num2 = 0; find_num(arr, len, &num1, &num2); printf("%d %d", num1, num2); printf("\n"); system("pause"); return 0; }