您的位置:首页 > 其它

关于异或运算的一个问题

2015-09-01 09:49 176 查看
之前在一个群里有一朋友问,给定一个整数序列,其中除了某个数n是单个出现外,其余的数都是成对出现,问怎么求出这个单个的数n,且尽可能小的空间复杂度和时间复杂度。

这个问题第一反应就是异或,因为之前对这类问题是有个大概想法的。因为我知道用异或可以不用第三方变量就可以交换两个数。尽管这想法自己也没去仔细思考原理。后来我仔细想了下,为什么异或能解决这个问题。

这个问题其实简化之后的问题是,给定一个二进制位序列(即0/1序列),无论这个序列中的数如何排列,最终的结果是不变的。

如果套用中学的办法,我们想证明这个问题

<=只需要证明给定的序列,交换任意两个位,整个序列的最终结果不变。

<=异或满足交换律和结合律

交换律:a^b=b^a 显然没问题

结合律:(a ^b)^c=a^(b^c)。根据异或规则,真值表马上可以证明。

但是看了上面的方法,我们好像并没有一种很顺畅的感觉。原因是,我们没有很好的理解异或,或者说简化这种运算。如果我们做一些简化,问题也许理解和证明起来会顺畅得多。

我们观察下某个值 x 和0/1异或的结果:

1^0 = 1, 0^0 = 0 所以 x^0 = x

也就是某个值异或0的作用就是保持原样

1^1 = 0 , 0^1 = 1 所以 x^1 = ~x

也就是某个值异或1的作用就是对这个值取反

于是任何一个序列中,从左往右依次做异或运算的结果,和序列中的0无关。可以直接去掉。剩下所有1组成的序列。最终的结果也只和1的个数有关系。初始值为0,依次异或1进行取反,所以如果有奇数个1,那结果就是1,偶数个1,结果就是0。这样就不需要通过交换律,结合律来非常理论的分析。毕竟那样只是证明了结果,并不算理解。

所以在32bit系统下,对一个数取反,和异或0xffffffff是相同的结果。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: