【算法练习】

【问题描述】

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

【来源】

微软面试题


【思路】

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值