我一直在尝试解决CTCI中的第一个问题,这涉及到位操作,我只是无法弄清楚作者如何在最终解决方案中准确地制作了掩码。有人可以解释" int left"," int right"和" int mask&#34 ;?的计算很高兴看到这些线正在为他提供的例子专门计算。
问题是: 您将获得两个32位数字,N和M,以及两个位,即i和j。写一个 将N和j之间的所有比特设置为N等于M的方法(例如,M成为的子串 N位于i,从j)开始。 例: 输入:N = 10000000000,M = 10101,i = 2,j = 6 输出:N = 10001010100
public static int updateBits(int n, int m, int i, int j) {
int max = ~0; /* All 1’s */
// 1’s through position j, then 0’s
int left = max - ((1 << j) - 1);
// 1’s after position i
int right = ((1 << i) - 1);
// 1’s, with 0s between i and j
int mask = left | right;
// Clear i through j, then put m in there
return (n & mask) | (m << i);
}
答案 0 :(得分:2)
解释&#34; int left&#34;,&#34; int right&#34;和&#34; int mask&#34;
的计算// 1’s through position j, then 0’s int left = max - ((1 << j) - 1);
(1 << j)
只有位置j
设置为1
((1 << j) - 1)
(减去1
)会将j
位置设置为j
以下(位于右侧)位置1
max - ((1 << j) - 1)
(从所有1中减去)产生上述的按位补码,即。即位于j
之上(位于左侧)并包括位置1
的所有位,以及j
位设置为0
即G。
j 1<<j (1<<j)-1 ~0-((1<<j)-1)
-------------------------------------------------------
0 000000000001 000000000000 111111111111
1 000000000010 000000000001 111111111110
2 000000000100 000000000011 111111111100
3 000000001000 000000000111 111111111000
4 000000010000 000000001111 111111110000
5 000000100000 000000011111 111111100000
6 000001000000 000000111111 111111000000
...
// 1’s after position i int right = ((1 << i) - 1);
(1 << i)
只有位置i
设置为1
((1 << i) - 1)
(减去1
)会将i
位置设置为i
以下(位于右侧)位置1
即G。
i 1<<i (1<<i)-1
-------------------------------------
0 000000000001 000000000000
1 000000000010 000000000001
2 000000000100 000000000011
...
// 1’s, with 0s between i and j int mask = left | right;
i = 2,j = 6:
left 111111000000
right 000000000011
| ------------
mask 111111000011
// Clear i through j, then put m in there return (n & mask) | (m << i);
(n & mask)
仅清除i
到j
- 1位(请参阅上面的mask
)(m << i)
将要设置的值移至所需的位位置(n & mask) | (m << i)
将移位的值位移到屏蔽的n
以你的例子:
n 010000000000
mask 111111000011
& ------------
n&mask 010000000000
m<<i 000001010100
| ------------
010001010100
现在,虽然此示例值会产生正确的结果,但我们可以看到updateBits()
的实现实际上是错误的,因为left
的{{1}}部分需要mask
由于位位置1
属于要屏蔽的子字符串,因此仅位于左侧和不位,包括位置j
。错误表明e。 G。值 n = 11111111111,m = 00000,i = 2,j = 6 :
j
值 m 仅被放入 i 位到 j-1 的位位置。
可以通过更改
来纠正错误n 011111111111
mask 111111000011
& ------------
n&mask 011111000011
m<<i 000000000000
| ------------
011111000011
到
int left = max - ((1 << j) - 1);