#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;
}