1: 自异或:x ^ x = 0
2: 交换律:x ^ y = y^ x
3: 结合律:(x ^ y) ^ z = x ^( y ^ z)
4: 还原律:z = x ^ y 则 x = z ^ y; y = x ^ z
1:从简单的开始。
如果我们需要求 2 的 23 次方。
门槛外程序猿写法是:
x = 2 * 2 * 2 * ..... * 2
入门级的程序猿,使用 for 循环:
for(i=0; i<23; i++) .....
标准的程序猿写法:
x= 1 << 23;
2: 整数的 乘2, 除2 运算:
乘 2 运算
[] (int x){ return x << 1; }
除 2 运算
[](int x) {return x >>= 1;}
注意: 这里,只能处理无符号整数!
3: 判断整数的奇偶性
我们只需要注意: 奇数最低位必然为1, 偶数最低位必然为0
所以,判断奇数我们可以使用:
[](intx){ return x & 1; }
类似的,判断偶数的方式为:
[](intx) { return !(x&1); }
4: 判断两个整数,符号是否一致
我们只需要判断最高位是否相同就行。我们可以使用异或运算。
[](int x, int y){ return (x^y) > 0; }
5:对于一个整数变量类型 T,可能各个平台,变量类型占用的字节数不一样,对可移植性有一定的影响。如果,我们需要获取这个变量类型的最大值,最小值?
5.1:对于有符号的数,最大值就是最高位为0,其它位为1
[](){T x=0; return (~x) >> 1; }
5.2:有符号数,最小值,就是最高位为 1, 其它位为 0
[](){ return 1 << (sizeof(T) - 1); }
5.3:无符号数,最小值就是0, 最大值,所有比特位为 1
[](){ T x=0; return ~x; }
6: 判断 整数 x 的 第 n 个 bit位(n从0开始计数,0表示最低位)是否为1
[](intx) { return (x>>n) & 1; }
7: 对 整数 x 的第 n 个bit位(n从0开始计数,0表示最低位),置位为1
[](int&x) { x |= (1<<n); }
8: 对 整数 x 的第 n 个bit位(n从0开始计数,0表示最低位),置位为0
[](int&x) { x &= ~(1<<n); }
9: 对 整数 x 的第 n 个bit位(n从0开始计数,0表示最低位),置反
[](int&x){ x ^= (1 << n); }
具体应用:
有n对两两相同的数,随机取出其中n-1对+1个,缺少一个数,求这个缺的数是多少。
如果使用两个循环一一比较,很耗费时间。
如果使用桶排序,则会造成空间浪费。
有没有时间复杂度为O(n)且空间复杂度为O(1)的算法呢?
当然是有的:
只要依次遍历这个n-1对+1个数,对其进行异或运算。
尤自异或可知,x^x=0,即可以消去n-1对数据。
剩下的0^x=x,即缺少的那个数据。
for(i=0;i<(n-1)*2+1;i++)
{
temp^=arr[i];
}
printf("%d",temp);
输出结果即所求数据