位操作破解编码面试

时间:2016-12-24 21:51:04

标签: binary mask operations

我一直在尝试解决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);
}

1 个答案:

答案 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)仅清除ij - 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);