2019-09-03 10:29:36
- x & (x - 1)
x & (x-1)相当于消除了 x 从右向左数遇到的第一个 1。
应用一、用 O(1) 时间检测整数 n 是否是 2 的幂次。
若 n 是 2 的幂次,则 n & (n - 1) == 0。
应用二、计算整数二进制中包含 1 的个数。
public int countOnes(int num) { int res = 0; while (num != 0) { num = num & (num - 1); res++; } return res; }
应用三、将整数A转成整数B,需要修改多少bit。
A ^ B 后对其中 1 的个数计数即可。
- 二进制子集快速计算
首先考虑特例,全1的情况,如111,其子集毫无疑问是001 - 111,可以不断的减1即可。
下面考虑一般情况,如1011,首先可以确定是其子集必然是比1011小的数字,所有如果我们依然去不断的减少1,并且进行判断无效位0,就可以得到其所有的子集,但是这种方法中间有很多的状态是无效的,如何快速得到子集呢。
先给一些结论:
1)subset <= num
2) subset1 > subset2 -> subset1 & num > subset2 & num
有了这两个结论就可以了,设s = num,s 是 num的子集,令s = (s - 1) & num,s 必然是第二大的子集,重复上述操作就能得到第三大的子集,一直到s == 0,就可以枚举掉所有的子集。
for (int s = mask; s > 0; s = (s - 1) & mask) { // s : mask 的子集 }
- x & -x
x & -x 在树状数组中有非常多的应用,可以通过x & -x来得到一个数的lowbit。这里的lowbit就是一个数末尾1所表示的数字,比如0100的lowbit就是4。