【问题标题】:represent an integer using binary in java language在java语言中使用二进制表示一个整数
【发布时间】:2011-08-19 00:25:02
【问题描述】:

问题来了:

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

例如: 输入: 整数 N = 10000000000,M = 10101,i = 2,j = 6; 输出: 整数 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中的代码(读完所有cmets后):

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);   
}        

【问题讨论】:

  • 你是什么意思 "如果我们使用 int... 但没有二进制表示?" 您绝对可以将 &amp; 和 | 应用于 Java 中的 int。你是说用二进制写一个int 文字吗?
  • 如果这是作业,请添加“作业”标签。
  • 是的,我说的是在二进制中定义一个 int 字面量,它类似于 C 中的这个语句: int N = 0x101010;
  • Java 中没有二进制文字。你有十进制,八进制和十六进制。但是您可以使用基数为 2 的 Integer.parseInt(String s, int radix) 从字符串表示开始。 download.oracle.com/javase/6/docs/api/java/lang/…

标签: java implementation bit-manipulation


【解决方案1】:

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

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

顺便说一句

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

是一个稍微清晰的蒙版结构

【讨论】:

  • 在 Java 7 中甚至还有一个二进制字面量:0b1010,在这里可能会派上用场。
  • 掩码很好,除了:想清除i和j之间的位,即j-i+1位。所以需要 -1 >> (32-i)
【解决方案2】:

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

  • 这里是j 连续的:(1 &lt;&lt; j)-1。
  • 这里是j 连续一个,后面是i 零:((1 &lt;&lt; j) - 1) &lt;&lt; i。
  • 这是一个位掩码,用于掩盖 x 中间的 j 位置:x &amp; ~(((1 &lt;&lt; j) - 1) &lt;&lt; i)。

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

【讨论】:

  • 在这个问题中,我们需要 (j-i+1) 个位置在 x 的中间
【解决方案3】:

我认为您误解了 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 的 i 右边的第一个位。
  • 过早的优化是万恶之源 - 这是 O(j-i)。如果您像在问题中那样使用复杂的掩码,则可以在 O(1) 中完成,但它的可读性会降低,而且 97% 的情况下,可读代码比高效代码更重要。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-05-21
    • 1970-01-01
    • 1970-01-01
    • 2015-01-21
    • 2014-09-19
    • 2017-08-23
    • 2011-11-10
    • 2019-08-04
    相关资源
    最近更新 更多