这道题其实是一道进阶题,它的初级是:
一个数组中只有一个数是单独出现的,其他的都是成对出现的,请找出这个数。
大家首先想到把这个数组遍历一遍,然后进行各种操作,但是这里推荐使用一种效率更高的方法——把数组中所有元素都异或一遍,最后得到的结果就是那个单独出现的数字。
例如数组元素:1 2 4 2 1。
1^2 = 3 (0001 ^ 0010 = 0011)
3^4 = 7 (0011 ^ 0100 = 0111)
7^2 = 5 (0111 ^ 0010 = 0101)
5^1 = 4 (0101 ^ 0001 = 0100)
最后结果为4代码实现:
int separate_figures(int *number, int size)
{
int i = 0;
int num = number[0];
for (i = 1; i <size; i++)
{
num ^= number[i];
}
return num;
}
int main()
{
int arr[] = { 1, 2, 3, 4, 3, 2, 1 };
int sz = sizeof(arr) / sizeof(arr[0]);
int ret = separate_figures(arr, sz);
printf("单独出现的数字数是:%d\n", ret);
system("pause");
return 0;
}
用这样的算法来做的话这道题就变的很简单了,现在来看看这道题的进阶版
数组中的只有2个数字是单独出现的,其他的都是成对出现的,请找出单独出现的这2个数字
代码如下:
#include <stdio.h>
#include <windows.h>
void find_single(int *number, int size)
{
int i = 0;
int key = number[1];
int n = 0;
int m = 0;
int flag = 1;
for (i = 1; i < size; i++)
{
key ^= number[i]; //把整个数组的元素异或,存到key里面
}
for (i = 0; i < 32; i++) //找出key的二进制序列里面第一次出现1的位置(从右到左查找)
{
if (key & (flag<<=i))
{
break;
}
}
if (flag)
{
for (i = 0; i < size; i++)
{
if (flag & number[i])
{
n ^= number[i];
}
else
{
m ^= number[i];
}
}
printf("%d, %d\n", n, m);
}
else
{
printf("这个数组中没有单独出现的数字!\n");
}
}
int main()
{
int arr[] = { 1, 1, 2, 2, 3, 3, 4, 5 };
int sz = sizeof(arr) / sizeof(arr[0]);
find_single(arr, sz);
system("pause");
return 0;
}