题目:

      给一组数,只有两个数只出现了一次,其他所有数都是成对出现的。怎么找出这两个数。编写函数实现。

题目分析:

        上次介绍了,对于一组数中只有一个数只出现一次,其他所有数都是成对出现的,我们采用了对全部数组元素进行异或,但是对于找出两个出现一次的数应该怎么解决呢?先对所有的元素进行异或,则结果为两个出现一次的数的异或结果,然后将结果转换为二进制,找出二进制数中的第一个1,然后根据这个1的判断条件进行分组,分为两组,分别对两个组的元素进行全部异或,则就找出两个不同的数。

例如:数组中的元素为下面这些数:

0000      --0

0000      --0

0001      --1

0001      --1

0010      --2

0011      --3

0011      --3

0100      --4

0100      --4

0101      --5

全部元素异或的结果为:0111    以最后面的1为条件,分为第一组(1、1、3、3、5)和第二组(0、0、2、4、4),分别对两组元素进行全部异或。

下面是具体的程序:

#define _CRT_SECURE_NO_WARNINGS 1#include 
#include 
 int find_get(int num)    //转换为二进制{    int get = 0;     while(num)    {            if(num % 2 == 1)   //返回转换的二进制中出现第一个的位数        {            return get;         }        get++;        num = num / 2;     }return -1;} void find_num(int arr[], int ret, int *p, int *q){     int i = 0;     int find = 0;     int pos = 0;     for(i = 0; i < ret; i++)   //将所有的数字异或,得到find     {         find ^= arr[i];     }     pos = find_get(find);     for(i = 0; i < ret; i++)     {         if (1 & (arr[i] >> pos))         {             *p ^= arr[i];         }         else         {            *q ^= arr[i];         }     }} int main(){     int arr[] = {1,1,2,2,3,3,4,5};     int ret = sizeof(arr) / sizeof(arr[0]);     int find = 0;     int num1 = 0;     int num2 = 0;     printf("输出只出现一次的数字:\n");     find_num(arr, ret, &num1, &num2);     printf("%d   %d", num1, num2);     system("pause");     return 0; }