【算法練習】

【問題描述】

接着前一篇文章的問題,若一個數組中所有的整數都出現了兩次,僅有兩個不同的數字出現一次,找出這兩個整數。

【來源】

微軟面試題


【思路】

從前一篇文章中可以知道,兩個相同的整數進行異或操作,結果爲0,這個問題我們也是將所有的整數進行異或操作,左後的結果肯定不是0,由於其他所有的整數都出現了兩次,所以進行異或操作後,其他數字都被消除(異或操作後是0),這個非零結果就是那兩個出現一次整數異或的結果,我們可以找到這個結果從低位開始第一個二進制不是0的位置,對於兩個整數異或後,出現1,說明其中一個整數在這個位置二進制位0,一個爲1.因此我們可以找到其中一個整數。知道了其中的一個整數,那麼將剛纔的結果與這找到的這個整數的反進行與操作,結果就是另一個整數。

【參考程序】

#include <iostream>
#include <Cstdlib>

using namespace std;

int GetFirstOne(int result)       //從低位開始,找到第一個二進制位是1的index
{
    int idx =0;
    while(result)
    {
        if(result & 1 == 1)
            break;
        else
            result>>1;
        idx ++;
    }
    return idx;
}
int GetNum(int *nums,int idx,int len)   //找到其中的一個出現一次的數
{
    int r = 1<<idx;
    int i,t =0;
    for(i =0;i<len;i++)
    {
        if(nums[i]&r == r)
        {
            t ^= nums[i];
        }
    }
    return t;
}
int GetOther(int *nums,int idx,int len)
{
    int r = 1<<idx;
    int i,t =0;
    for(i =0;i<len;i++)
    {
        if(nums[i]&r != r)
        {
            t ^= nums[i];
        }
    }
    return t;
}
int main()
{
    int n,i,*nums,r,idx,num1;
    while(cin>>n)
    {
        nums = (int *)malloc(sizeof(int)*n);
        r =0;
		i =0;
        while(i < n){
            cin>>nums[i];
            r ^=nums[i];
			i++;
        }
        idx = GetFirstOne(r);
        num1 = GetNum(nums,idx,n);
        cout<<idx<<endl
            <<num1<<endl
            <<(r &(~ num1))<<endl;
    }
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章