3

我正在计算给定一组位的 int 等效值并将其存储在内存中。从那里,我想从原始位掩码中确定所有 1 值位。例子:

33 --> [1,6]
97 --> [1,6,7]

在 Java 中实现的想法?

4

5 回答 5

7

BitSet

用于java.util.BitSet存储一组位。

根据设置的位,这是从 a 转换int为 a的方法:BitSetint

static BitSet fromInt(int num) {
    BitSet bs = new BitSet();
    for (int k = 0; k < Integer.SIZE; k++) {
        if (((num >> k) & 1) == 1) {
            bs.set(k);
        }
    }
    return bs;
}

所以现在您可以执行以下操作:

System.out.println(fromInt(33)); // prints "{0, 5}"
System.out.println(fromInt(97)); // prints "{0, 5, 6}"

为了完整起见,这里是反向转换:

static int toInt(BitSet bs) {
    int num = 0;
    for (int k = -1; (k = bs.nextSetBit(k + 1)) != -1; ) {
        num |= (1 << k);
    }
    return num;
}

因此,将两者组合在一起,我们总是会得到原始数字:

System.out.println(toInt(fromInt(33))); // prints "33"
System.out.println(toInt(fromInt(97))); // prints "97"

基于 0 的索引

请注意,这使用基于 0 的索引,这是更常用的位索引(以及 Java 中的大多数其他内容)。这也更正确。在下文中,^表示取幂:

33 = 2^0 + 2^5 = 1 + 32          97 = 2^0 + 2^5 + 2^6 = 1 + 32 + 64
33 -> {0, 5}                     97 -> {0, 5, 6}

但是,如果您坚持使用基于 1 的索引,则可以在上面的代码片段中使用bs.set(k+1);和。(1 << (k-1))然而,我强烈反对这个建议。

相关问题

于 2010-05-28T22:01:24.760 回答
2

对于摆弄,java.lang.Integer 有一些非常有用的静态方法。尝试将此代码作为您的问题的起始基础:

public int[] extractBitNumbers(int value) {
    // determine how many ones are in value
    int bitCount = Integer.bitCount(value);
    // allocate storage
    int[] oneBits = new int[bitCount];
    int putIndex = 0;
    // loop until no more bits are set
    while (value != 0) {
        // find the number of the lowest set bit
        int bitNo = Integer.numberOfTrailingZeros(value);
        // store the bit number in array
        oneBits[putIndex++] = bitNo+1; 
        // clear the bit we just processed from the value
        value &= ~(1 << bitNo);      
    }
    return oneBits;
}
于 2010-05-29T07:22:25.247 回答
1

我可以向您展示 C# 实现,Java 应该非常相似。

整数值 = 33;
整数索引 = 1;

而(值> 0)
{
   如果 ((值 % 2) == 1)
      Console.WriteLine(index);

   索引++;
   值/= 2;
}
于 2010-05-28T21:49:01.183 回答
1

如果你想得到一个这样的数组,你可能需要循环你想要检查&整数的位数,每一步都移动 1 位。

像(伪)这样的东西:

Init array
mask = 1
for (0 to BitCount):
  if Integer & mask
    array[] = pos
  mask << 1
于 2010-05-28T21:51:14.923 回答
1

一个有点复杂的变化会是这样的:

int[] getBits(int value) {
  int bitValue = 1;
  int index = 1;
  int[] bits = new int[33];

  while (value >= bitValue)
  {
    bits[index++] = (value & bitValue);
    bitValue << 1; // or: bitValue *= 2;
  }
  return bits;
}

请注意,由于这些位按照您的要求从 1 开始索引,bits[0]因此未使用。

于 2010-05-28T21:54:31.017 回答