与、异或的应用场景

& 的应用(权限值)
2^0=1, 相应 2 进制为 "0001" (在这里 ^ 我表示成"次方", 即: 2 的 0 次方, 下同)
2^1=2, 相应 2 进制为 "0010"
2^2=4, 相应 2 进制为 "0100"
2^3=8, 相应 2 进制为 "1000"
...

要判断一个数在某些数范围内就可以使用 & 运算符(数值从上面的表中得来)
如: 7=4|2|1 (你也可以简单理解成 7=4+2+1)
用 & 来操作,可以知道 7&6、7&5、7&4、7&3 、7&2、7&1 都是真的,而如果 7&8 则是假的
判断权限使用 & (是, 返回非 0; 不是, 返回 0)

Java hashMap 中的实现用的了与巧妙的避开了除法取余的效率问题,可查阅相关资料。
判断两个字符串是否为子串也可以用或跟与来解决。

^ 的应用(交换值)
a ^ b ^ c = (a ^ b) ^ c = a ^ (b ^ c)
d = a ^ b ^ c => a = d ^ b ^ c
x^0 = x         => x^x = 0
a^(b^b) = a  => a^b^b = a

        a---------------------------b
a^=b  a^b---------------------------b
b^=a  a^b---------b^(a^b) => a
a^=b  a^b^a => b---------------a
        b---------------------------a

找出重复数
解法1: 数组累和 - (1+2+3+...+.. + 999 + 1000) = 所求结果
解法2: 异或
将所有的数全部异或, 将得到的结果与 1^2^3^...^1000 的结果进行异或, 得到的结果就是重复数

但是这个算法虽然很简单, 但证明起来并不是一件容易的事情, 这与异或运算的几个特性有关系
首先是异或运算满足交换律、结合律
所以, 1^2^...^n^...^n^...^1000, 无论这两个 n 出现在什么位置, 都可以转换成为 1^2^...^1000^(n^n) 的形式

其次, 对于任何数 x, 都有 x ^ x = 0, x ^ 0 = x
所以 1^2^...^n^...^n^...^1000 = 1^2^...^1000^(n^n) = 1^2^...^1000^0 = 1^2^...^1000 (即序列中除了 n 的所有数的异或)

令, 1 ^ 2 ^... ^ 1000 (序列中不包含 n) 的结果为 T
则 1 ^ 2 ^... ^ 1000 (序列中包含 n) 的结果就是 T ^ n
T ^ (T ^ n) = n
所以, 将所有的数全部异或, 得到的结果与 1^2^3^...^1000 的结果进行异或, 得到的结果就是重复数

转载于:https://my.oschina.net/wellben/blog/26221

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值