1. 程式人生 > >C語言編程 找出數列中只出現一次的兩個數

C語言編程 找出數列中只出現一次的兩個數

i++ 有一個 length 無法 system ret void 分析 一位

原題:
一個數組中只有兩個數字是出現一次,其他所有數字都出現了兩次。
找出這兩個只出現一次的數字,編程實現。

此題要用到在數列中找出只出現一次的一個數字的方法
參考https://blog.51cto.com/14232799/2382172

此題明顯無法一次性將兩個數都找出,所以需要將數列分為兩部分,每一部分有一個只出現一次的數,那麽此時需要的就是分離數列的條件。

沿用找出一個數時的思想,將數列進行相互異或,但這次所得的值不是只出現一次的那個數了,因為只出現一次的數有兩個,所以此次計算得到的是只出現一次的兩個數的異或值。

在得到這個值後進行分析,假如得到值是4,二進制碼是0100
參照異或的定義,0代表此位兩個數的值相同,1代表此位兩個數的值不同。

eg:
只出現一次的兩個數是2和6
2的二進制碼是
0010
6的是
0110
計算得到的值(兩個數異或)就是0100,表示第三個二進制位兩個數不同

得到了此條件,就可以將數列分為第三個二進制位為1第三個二進制位為0兩個數列
再將每個數列采用找出一個數字的方法找出數字即可。

源代碼:

#include<stdio.h>
#include<stdlib.h>
int First(int arr[], int length)//得到只出現一次的兩個數的異或
{
    int i,result=0;
    for (i = 0; i < length; i++)
    {
        result ^= arr[i];
    }
    return result;
}
void Second(int arr[],int i,int length,int* num1, int* num2)//將數列分為兩個數列而且找出數字
{
    int j;
    for (j = 0; j < length; j++)
    {
        if (arr[j] >> i == 0)//分離條件
        {
            *num1 ^= arr[j];
        }
        if (arr[j] >> i == 1)//同上
        {
            *num2 ^= arr[j];
        }
    }
}
int main()
{
    int i = 0,num1=0,num2=0;//i用來存儲二進制位上哪一位兩個只出現一次的的數字是不同的
    int* k1=&num1,* k2=&num2;//存儲要找的兩個數
    int arr[] = { 1, 4, 6, 8, 2, 8, 4, 1 };
    int length = sizeof(arr) / sizeof(arr[0]);
    int result = First(arr, length);
    while (((result >> i) & 1)==0)//找出異或值中二進制序列不同是在哪一位
    {
        i++;
    }
    Second(arr,i,length,k1,k2);//數列分離為兩個數列和找出數字
    printf("兩個數字為%d和%d", num1, num2);
    system("pause");
    return 0;
}

C語言編程 找出數列中只出現一次的兩個數