问题在于:
你有2个32位数字,N& M和两位位置,i&学家写一个方法来设置i和j之间的所有位在N中等于M(例如,M成为位于i的N的子串 并从j)开始
例如: 输入: int N = 10000000000,M = 10101,i = 2,j = 6; 输出: int N = 10001010100
我的解决方案:
step 1: compose one mask to clear sets from i to j in N
mask= ( ( ( ((1<<(31-j))-1) << (j-i+1) ) + 1 ) << i ) - 1
for the example, we have
mask= 11...10000011
step 2:
(N & mask) | (M<<i)
问题: 实现算法的方便数据类型是什么?例如 我们在C中有int n = 0x100000,因此我们可以在n上应用按位运算符。 在Java中,我们有BitSet类,它有清晰的set方法,但不支持 左/右移位算子;如果我们使用int,它支持左/右移位,但是 没有二进制表示(我不是在谈论二进制字符串表示) 实现这个的最佳方法是什么?
java中的代码(阅读完所有评论后):
int x = Integer.parseInt("10000000000",2);
int x = Integer.parseInt("10101",2);
int i = 2, j = 6;
public static int F(int x, int y, int i, int j){
int mask = (-1<<(j+1)) | (-1>>>(32-i));
return (mask & x ) | (y<<i);
}
答案 0 :(得分:3)
逐位运算符|
,&
,^
和~
以及十六进制文字(0x1010
)都可用于java
如果该约束保持int
将是有效数据类型,则32位数为int
顺便说一句
mask = (-1<<j)|(-1>>>(32-i));
是一个稍微清晰的面具构造
答案 1 :(得分:0)
Java int
拥有您需要的所有操作。我并不完全理解你的问题(现在太累了),所以我不会给你一个完整的答案,只是一些提示。 (如果需要,我稍后会修改它。)
j
行:(1 << j)-1
。j
行,其后是i
零:((1 << j) - 1) << i
。j
中间的x & ~(((1 << j) - 1) << i)
位置。尝试使用Integer.toBinaryString()
查看结果。 (它们也可能对负值或太大的值给出奇怪的结果。)
答案 2 :(得分:0)
我认为你误解了Java是如何工作的。所有值都表示为引擎盖下的“一系列位”,其中包含整数和长整数。
根据您的问题,一个粗略的解决方案是:
public static int applyBits(int N, int M, int i, int j) {
M = M << i; // Will truncate left-most bits if too big
// Assuming j > i
for(int loopVar = i; loopVar < j; loopVar++) {
int bitToApply = 1 << loopVar;
// Set the bit in N to 0
N = N & ~bitToApply;
// Apply the bit if M has it set.
N = (M & bitToApply) | N;
}
return N;
}
我的假设是:
i
是N
中设置的最右侧(最不重要)位。M
最右边的位从右侧映射到N
的{{1}}位。