您的位置:首页 > 其它

一组数据中只有一个数字出现一次 ;其他所有数字都是成对出现的请找出这个数字。

2016-11-25 23:14 495 查看
题目:

一组数据里边数都是成对出现;里边可能有一个单数、也可能没有、还有可能有两个单数三种情况;

思想:

【一】

如果这组数是奇数个,例如{1,3,5,7,1,3,5};让每个数依次异或则就剩下7;

【二】

如果这组数是偶数个,例如{1,3,5,1,3,5};每个数依次异或则结果为零;

【三】

如果这组数是偶数个,还有一种情况是有两个单数;例如{3,5,7,3,5,11};假设数在电脑里边不是32位而是4位为了方便讲解

3:0011

5:0101

7:0111

3:0011

5:0101

11:1011 ①让所有数依次异或则得1100

②因为后边两位是0则说明两个单数是从倒数三位不同的然后让每个数右移两位 则数据会变为

3: 0000

5: 0001

7: 0001

3: 0000

5: 0001

11:0010

然后把末尾为零的依次异或 在这组数据里是3 3 11;

把末尾为1的依次异或 在这组数据里是5 7 5;

#include<stdio.h>
#include<math.h>
void find_mum(int  * arr, int size)
{
int num = 0;
int num1 = 0;
int num2 = 0;
int i = 0;
int flag = 0;
int n = 0;
if ((size % 2) == 1)  //如果是奇数个数  那么就有一个单数
{
for (i = 0; i < size; i++)
{
num = num ^ *(arr + i);    //所有数异或 单数自然出来
}
printf("单数:%d\n", num);
}
else          //这里有两种情况 一种是没有单数  还有是两个单数
{
for (i = 0; i < size; i++)
num = num^ *(arr + i);
if (num == 0)            //如果是零说明没有单数
{
printf("没有单数\n");
}
else  //这种情况有两个单数
{
while (!(num & 1))
{
flag++;
num = num >> 1;
}

for (i = 0; i < size; i++)
{
n = arr[i] >> flag;
if (n & 1)
{
num1 = num1 ^ *(arr + i);
}
else
{
num2 = num2 ^ *(arr + i);
}
}
printf("两个单数 :\n%d\n%d\n ", num1, num2);
}
}
}
int main()
{
int arr[] = { 1, 3, 5, 7, 1, 8, 3, 5 };
int size = sizeof(arr) / sizeof(arr[0]);
find_mum(arr, size);
system("pause");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐