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

来源:互联网 发布:php 设置session路径 编辑:程序博客网 时间:2024/04/28 12:09

题目:
一组数据里边数都是成对出现;里边可能有一个单数、也可能没有、还有可能有两个单数三种情况;
思想:
【一】
如果这组数是奇数个,例如{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;}
0 0
原创粉丝点击