繁体   English   中英

用Java语言中的二进制表示整数

[英]represent an integer using binary in java language

这是问题所在:

您将获得2个32位数字N和M,以及两个位置i和j。 编写一种方法来将N中i和j之间的所有位设置为等于M(例如,在位于i处并从j开始时,M成为N的子串)

例如:输入: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);   
}        

按位运算符| &^~以及十六进制文字( 0x1010 )在Java中都可用

如果该约束保持不变,则int 32位数字int将是有效的数据类型

顺便说一句

mask = (-1<<j)|(-1>>>(32-i));

是面罩的结构稍微清晰一点

Java的int具有您所需的所有操作。 我还不太了解您的问题(现在太累了),所以我不会给您完整的答案,只是一些提示。 (如果需要,我会在稍后进行修改。)

  • 这是连续的j个: (1 << j)-1
  • 这是连续j个,后跟i零: ((1 << j) - 1) << i
  • 这是一个位掩码,它屏蔽了x中间的j位置: x & ~(((1 << j) - 1) << i)

尝试使用Integer.toBinaryString()查看结果。 (对于负值或太大的值,它们也可能给出奇怪的结果。)

我认为您误解了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;
}

我的假设是:

  • iN中设置的最右边(最低有效)位。
  • M的最右边的位从右边映射到N的第i位。
  • 过早的优化是万恶之源-这就是O(ji)。 如果像问题中那样使用复杂的掩码,则可以在O(1)中进行操作,但是它的可读性不高,可读代码比有效代码重要的时间是97%。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM