找出一组数中只出现一次的两个数,其他所有数都是成对出现的

时间:2022-03-13 14:29:53

题目:

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


题目分析:

        上次介绍了,对于一组数中只有一个数只出现一次,其他所有数都是成对出现的,我们采用了对全部数组元素进行异或,但是对于找出两个出现一次的数应该怎么解决呢?先对所有的元素进行异或,则结果为两个出现一次的数的异或结果,然后将结果转换为二进制,找出二进制数中的第一个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 <stdio.h>
#include <stdlib.h>
 
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;
 
}



本文出自 “无心的执着” 博客,转载请与作者联系!