利用ASCII码与位运算异或进行大小写转换
大小写字母在ASCII码中差32(1<<5)
c^=1<<5
计算数字中1的数量
int countOne(int n){
int count = 0;
while (n != 0){
count++;
n = (n-1) & n;// 去掉最右边一个1
}
return count;
}
不用临时变量交换值
numbers[0] ^= numbers[1];
numbers[1] ^= numbers[0];
numbers[0] ^= numbers[1];
最后一个1
num&-num
去掉最右边一个1
n &= n - 1
最低位 0 改 1
n |= n + 1
把右边连续的1变成0
x & (x+1)
把末k位变成1
x | ((1 << k)-1)
末k位取反
x ^ ( 1 << k - 1 )
绝对值
(n ^ (n >> 31)) - (n >> 31)
n>0 则 n >> 31 = 0 ,即为 n^0-0
n<0 则 n >> 31 = -1 ,即为 n^-1 + 1 同 ~n+1 ,即补码
符号
(n >> 31) | (~((~n + 1) >> 31) + 1)
(~n + 1) >> 31 正数为 -1 ,负数为 0。
~((~n + 1) >> 31) 取反后正数为 0 ,负数为 -1
(~((~n + 1) >> 31) + 1) 加一后正数为 1 ,负数为 0
(n >> 31) | 正数为 0,负数为 -1 和上一步进行或运算。则正数为 1,负数为 -1
取最大值
int max(int a, int b){
return (b & ((a - b) >> 31)) | (a & (~(a - b) >> 31));
}
枚举集合
# 设集合为 s,从大到小枚举 s 的所有非空子集 sub
for (int sub = s; sub > 0; sub = (sub - 1) & s) {
// 处理 sub 的逻辑
}
# 设元素范围从 0 到 n−1,从空集枚举到全集
for (int s = 0; s < (1 << n); s++) {
// 处理 s 的逻辑
}
Gosper's Hack
枚举在最大 n 个bit位 ,中有 k 个bit为 1 的所有数
int subset = (1 << k) - 1;
while (subset < (1 << n)) {
// do something
int lb = subset & -subset;
int x = subset + lb;
subset = ((subset ^ x) / lb >> 2) | x;
}