一个整形数组里除了两个数字以外,其他数字都出现了两次,找出这两个只出现一次的数字。...

用异或运算来解题,首先看一下异或的特点:

1.0^0=0,0^1=1,1^0=1,1^1=0,即相同取0,不同取1,那么相同的两个整数异或结果为0,任何整数与0异或都等于其本身

2.异或满足交换律,即a^b^c=a^c^b

所以,将数组中的数从头到尾依次异或,出现偶数次的数异或都为0,最终结果是两个只出现一次的数字异或的结果,由于这两个数字不同,异或的结果一定不为0,即其二进制表示形式中一定存在某一位为1,找到第一个为1的位,假设是第N位,那么在对应的这一位上,这两个数一个为0,一个为1,根据第N位是否为1,将原数组分成两个子数组,这两个子数组分中都只包含一个只出现了一次的数,其他的数都出现了两次,两个子数组中的元素分别异或,就得到了两个只出现一次的数。

 

 1 #include<iostream>
 2 using namespace std;
 3 bool IsBit1(int num,unsigned int indexBit)   //判断num的第indexBit位是否为1,位数从0算起
 4 {
 5     num=num>>indexBit;   //将num的第indexBit移到末尾
 6     return(num&1);     //1除了第一位,其余为均为0,&操作结果必为0,决定结果的只是第indexBit位
 7 }
 8 
 9 unsigned int FindFirstBitIs1(int num)
10 {
11     int indexBit=0;
12     while(num>0&&(num&1)==0)
13     {
14         indexBit++;
15         num=num>>1;
16     }
17     return indexBit;
18 }
19 
20 void FindNumsAppearOnce(int data[],int length,int &num1,int &num2)
21 {
22     if(length<2) return;
23     int result=0;
24     for(int i=0;i<length;i++)
25         result=result^data[i];
26     int indexBit=FindFirstBitIs1(result);
27     num1=num2=0;
28     for(int i=0;i<length;i++)
29     {
30         if(IsBit1(data[i],indexBit))   //根据第indexBit是否为1将数组分成两组,并进行异或
31             num1=num1^data[i];
32         else
33             num2=num2^data[i];
34     }
35 
36 }
37 void main()
38 {
39     int a[10]={1,1,2,2,3,3,4,4,5,6};
40     int num1,num2;
41      FindNumsAppearOnce(a,10,num1,num2);
42      cout<<num1<<" "<<num2;
43 
44 }

结果:

 

转载于:https://www.cnblogs.com/mrlsx/p/5442643.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值