寻找无序互异数组中丢失的数

1.寻找无序互异数组中丢失1个数。

异或操作相当于逻辑加。

代码:

int Find1(int seq[], int n, int&a)

{

    a = 0;

    for(int i =0; i < n; i++)

    {

        a^=seq[i];

    }

    return 0;

}

2.寻找无序互异数组中丢失2个数。需要将全部数字分成两组A,B,A缺少a,B缺少b。

void Find2(int seq[], int n, int& a, int& b)
{
    XOR
    int xors = 0;
    for(int i = 0; i < n; i++)
        xors ^= seq[i];

    get different bit
    int diff = lowbit(xors);

   
    a = 0;
    b = 0;
    for(int i = 0; i < n; i++)
    {
        if(diff & seq[i])
            a ^= seq[i];
        else
            b ^= seq[i];
    }
}

 

2.寻找无序互异数组中丢失3个数。需要分成3组A,B,C,A缺少a,B缺少b,C缺少c。

首先s= a^b^c。

假设s的某一个bit=0

a,b,c有两种情况

   z1.1  z1.2

a    1       0

b    0       0

c    1       0

假设s的某一个bit=1

   z1.3   z1.4

a     0      1

b     1      1

c     0      1

s中所有的bit生成情况只能是z1.1,z1.2,z1.3,z1.4中的一种。而且z1.1和z1.3的出现次数一定大于2次。否则只有1次的话,s只能由两个数组成。

假设a^b, b^c, c^a任意一bit位

       z2.1   z2.2     z2.3      z2.4

a^b   1         1          1          0

b^c   1         1          0          0

c^a   1         0          0          0

因为(a^b)^(b^c)^(c^a)=0 所以z2.1,z2.3不符和。只能出现z2.2,z2.4。

z2.2对应a,b,c状态:

    z1.1   z1.3

a     1        0

b     0        1

c     1        0

这种情况可以用于区分a,b,c

z2.4对应a,b,c状态:

    z1.4   z1.2

a     1        0

b     1        0

c     1        0

这种情况不能用于区分a,b,c

------------------------------

所以利用z2.2的情况可以用来区分数据。又因为z1.1和z1.3的次数一定>2,所以 z2.2的出现次数一定>2

所以a^b, b^c, c^a某一bit位只能出现1,1,0,这个bit位可以用来区分数据,分组。 

假设a^b, b^c, c^a某2个bit位出现1,1,0情况,用来分组。出现两种情况。

z3.1:

         bit1   bit2

 

a^b    1       0

b^c    1       1

c^a    0       1

 

 

z3.2:

 

         bit1   bit2

 

a^b    1       1

b^c    1       1

c^a    0       0

 

----------------------------

解z3.1的情况:

假设bit1和bit2都是最后两位不同的bit位。

取最后一个1,变为:

 

         bit1   bit2

a^b    1       0

b^c    0       1

c^a    0       1

则(a^b)^(b^c)^(c^a)= 1 0。因为只有a^b = 1 0。

x ^ c = a^b = 1 0这种情况。所以只需要x^每个数据,当出现 1 0的情况下,这个数据就是候选c,但是其他的数字出现偶数,所以用^存储在一个变量中就可以消除相同,最后剩下的就是c。

解z3.2的情况

 

假设bit1和bit2都是最后两位不同的bit位。

取最后一个1,变为:

 

 

         bit1   bit2

a^b    0       1

b^c    0       1

c^a    0       0

则(a^b)^(b^c)^(c^a)= 0 0。因为只有a^b = 0 0。因为只有c^a= 0 0。

x^b = c ^ a = 0 0这种情况。所以只需要x^每个数据,当出现 0 0的情况下,这个数据就是候选c,但是其他的数字出现偶数,所以用^存储在一个变量中就可以消除相同,最后剩下的就是b。

-----------------

取出一个数据后,就可以计算剩下的数据。

void Find3(int seq[], int n, int& a, int& b, int& c)
{
    XOR
    int xors = 0;
    for(int i = 0; i < n; i++)
        xors ^= seq[i];

   
    int flips = 0;
    for(int i = 0; i < n; i++)
        flips ^= lowbit(xors ^ seq[i]);
    flips = lowbit(flips);

    get one of three
    a = 0;
    for(int i = 0; i < n; i++)
    {
        if(lowbit(seq[i] ^ xors) == flips)
            a ^= seq[i];
    }

    swap a with the last element of seq
    for(int i = 0; i < n; i++)
    {
        if(a == seq[i])
        {
            int temp = seq[i];
            seq[i] = seq[n - 1];
            seq[n - 1] = temp;
        }
    }

    call Find2() to get b and c
    Find2(seq, n - 1, b, c);
}


 

 

 

 

 

 

2.寻找无序互异数组中丢失4个数。需要分成4组A,B,C,D,A缺少a,B缺少b,C缺少c,D缺少d

 

首先s= a^b^c^d。

假设s的某一个bit=0

a,b,c有两种情况

   z1.1  z1.2  z1.3

a    1       1      0

b    0       1      0

c    1       1      0

d    0       1      0

假设s的某一个bit=1

   z1.4   z1.5 

a     0      1

b     1      1

c     0      1

d     0      0

其中z1.2和z1.3的情况是无用的。只有z1.1和z1.4和z1.5可以用来区分

              z2.1   z2.2  z2.3  z2.4  z2.5

a^b^c       1        1      1       1      0

a^b^d       1        1      1       0      0

a^c^d       1        1      0       0      0

b^c^d       1        0      0       0      0

-----------------------

z2.1的情况下

       z1.2

a        1

b        1

c        1

d        1

z2.2情况下

 

       z1.4

a        1 

b        0  

c        0 

d        0 

 

z2.3情况下

 

       z1.1    

a        1         

b        1         

c        0         

d        0       

z2.4情况下

 

       z1.5

a        1

b        1

c        1

d        0

 

z2.5情况下

 

       z1.3

a        0

b        0

c        0

d        0

 

因为z1.2和z1.3不可用,对应z2.1和z2.5不可用。

剩下3种情况:

 

              z2.2  z2.3  z2.4

a^b^c       1      1       1 

a^b^d       1      1       0 

a^c^d       1      0       0 

b^c^d       0      0       0 

 

 

讨论z2.2的情况

 

              bit1   bit2

a^b^c       1      1

a^b^d       1      1

a^c^d       1      1 

b^c^d       0      0

 

取最后一个1结果是0 1

 

              bit1   bit2

a^b^c       1      1

a^b^d       0      1 

a^c^d       1      1 

b^c^d       1      0

 

取最后一个1结果是1 1

 

 

 

讨论z2.3的情况

 

              bit1   bit2

a^b^c       1      1

a^b^d       1      1

a^c^d       0      0 

b^c^d       0      0

 

取最后一个1结果是 0 0

 

              bit1   bit2

a^b^c       1      1

a^b^d       0      1 

a^c^d       0      0 

b^c^d       1      0

取最后一个1结果是1 0

 

              bit1   bit2

a^b^c       0      1

a^b^d       0      1 

a^c^d       1      0 

b^c^d       1      0

 

 

取最后一个1结果是 0 0

 

讨论z2.4的情况

 

              bit1   bit2

a^b^c       1      1

a^b^d       0      0

a^c^d       0      0 

b^c^d       0      0

 

取最后一个1结果是 0 1

 

              bit1   bit2

a^b^c       1      0

a^b^d       0      1 

a^c^d       0      0 

b^c^d       0      0

 

 

 

取最后一个1结果是 1 1

貌似情况太多了,不可以这么分析。结果再议。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值