求数组中只出现一次的数字(算法)

  首先,我们先考虑简单的情况下,就是只有一个出现一次的数字,其余数字都出现2次,这样我们可以采用一种很巧妙的方法:“异或”。

void findNumAppearOnce(int date[],int length,int &num)
{
       if(length<2)
              return;
        num=0;
        for(int i=0;i<length;i++)
       {
              num ^=date[i];
       }
}

 然后,我们考虑有两个出现一次的数字的情况。同理,我们依然采用上面的方法,由于两个出现一次的数字肯定不相同,最后的结果就是这两个数字的异或结果,因而这个结果必不为0,至少存在一位为1(就是由于这两个出现一次的数字的同一位上:一个为0,一个为1)。因此,我们首先找到一位不为0的二进制位n,把所有的数据按照此位划分为两组,这两组的第n位分别为0和1,这样就能保证每组中必然包含一个仅出现一次的数字。

  源代码参考:剑指Offer

  代码如下:

#include <iostream>
using namespace std;
//从左向右移动,获取第一个为1的位数
unsigned int FindFirstBitIs1(int num)
{
    int indexBit = 0;
    while(((num&1)==0)&&(indexBit<32))
    {
        num=num>>1;
        ++indexBit;
    }
    return indexBit;
}
//对数据分组
bool IsBit1(int num,unsigned int indexBit)
{
    //移动相应的位数,让相对位置移动到最后一位上
    num=num>>indexBit;
    //例如:1001101 ^ 0000001 这样的情况为0 ; 1010110 ^ 0000001 这样的情况为1
    return (num & 1);
}

void findNumAppearOnce(int date[],int length,int &num1, int &num2)
{    
    if (length<2)
        return;

    //get num1^num2
    int resultExclusiveOR = 0;
    for (int i=0;i<length;i++)
        resultExclusiveOR ^=date[i];
    
    unsigned int indexOf1 = FindFirstBitIs1(resultExclusiveOR);

    num1=0;num2=0;
    for (int j=0;j<length;j++)
    {
        if(IsBit1(date[j],indexOf1))
            num1 ^=date[j];
        else
            num2 ^=date[j];
    }
    
}

int main(int argc,char* argv[])
{
    int a[6];
    for(int i=0;i<6;i++)
        cin>>a[i];
    
    int num1,num2;
    findNumAppearOnce(a,6,num1,num2);
    cout<<"num1="<<num1<<endl;
    cout<<"num2="<<num2<<endl;
    return 0;
}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值