算法中的技巧
(1)如果现在有整数区间是由2的次方或通过不同的2的次方相加得到, 例如:[1 ~ 2], [1 ~ 4], [1 ~ 6], 这其中的6就是通过(2^2 + 2)得到的;
现在给你一个整数区间 [1 ~ n], 你需要找出属于 [1 ~ n]这个区间的最大上述形式的区间,怎么做?
例如:给你区间 [1 ~ 7], 可以划分为 [1 ~ 6] + [7];
以下给出划分区间的方法:
只要求出最大端点值即可, 可以联想2^0 + 2^1 + 2^2 + 2^3 +······ 不就是区间的端点吗?这个端点表示形式不就是二进制转换到十进制的表示形式吗?
那好我们现在可以通过一个简单的算法实现 : 给出的区间右端点为n, 那么通过 n & (-n) 得到的值就是 n 与 所求右端点的差值;这样差值一出就可以简单算出右端点的值了;
例如 [1 ~ 7] 区间中n = 7, 则 7 & (-7) = 1, 所以右端点的值为7 - 1 = 6;故可以划分为[1 ~ 6] + [7];
这里的n & (-n)是“与”运算:7的二进制为 111, -7的二进制为7的 ‘补码’ 即 先得到7的 ‘反码’ 再加1得;7中得0变成1,1变成0得 000, 再加1得 001, 再通过与运算得
1 1 1
& 0 0 1
------------ 故结果为1;
0 0 1