【算法练习】

来源:互联网 发布:淘宝商城加盟代理 编辑:程序博客网 时间:2024/05/01 05:58

【问题描述】

接着前一篇文章的问题,若一个数组中所有的整数都出现了两次,仅有两个不同的数字出现一次,找出这两个整数。

【来源】

微软面试题


【思路】

从前一篇文章中可以知道,两个相同的整数进行异或操作,结果为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;}

0 0
原创粉丝点击