【問題描述】
接着前一篇文章的問題,若一個數組中所有的整數都出現了兩次,僅有兩個不同的數字出現一次,找出這兩個整數。
【來源】
微軟面試題
【思路】
從前一篇文章中可以知道,兩個相同的整數進行異或操作,結果爲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;
}