& 的应用(权限值)
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 的结果进行异或, 得到的结果就是重复数