存储位掩码的 int 值 - 提取 1 个值位

发布于 2024-09-03 12:52:31 字数 133 浏览 2 评论 0原文

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

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

在 Java 中实现的想法?

I am calculating the int equivalent of a given set of bits and storing that in memory. From there, I would like to determine all 1 value bits from the original bitmask. Example:

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

Ideas for an implementation in Java?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

绮烟 2024-09-10 12:52:31

BitSet

使用 java.util.BitSet 来存储一组位。

以下是根据 int 中设置的位将 int 转换为 BitSet 的方法:

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)) 。然而,我强烈反对这一建议。

相关问题

On BitSet

Use java.util.BitSet to store, well, a set of bits.

Here's how you can convert from an int to a BitSet, based on which bits in the int is set:

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

So now you can do the following:

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

And just for completeness, here's the reverse transformation:

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

So composing both together, we always get back the original number:

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

On 0-based indexing

Note that this uses 0-based indexing, which is the more commonly used indexing for bits (and most everything else in Java). This is also more correct. In the following, ^ denotes exponentiation:

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

If you insist on using 1-based indexing, however, you can use bs.set(k+1); and (1 << (k-1)) in the above snippets. I would advise strongly against this recommendation, however.

Related questions

给妤﹃绝世温柔 2024-09-10 12:52:31

对于位摆弄,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;
}

For bit fiddling, java.lang.Integer has some very helpful static methods. Try this code as a starting base for your problem:

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;
}
久随 2024-09-10 12:52:31

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

int value = 33;
int index = 1;

while (value > 0)
{
   if ((value % 2) == 1)
      Console.WriteLine(index);

   index++;
   value /= 2;
}

I can show you C# implementation, Java should be very similar.

int value = 33;
int index = 1;

while (value > 0)
{
   if ((value % 2) == 1)
      Console.WriteLine(index);

   index++;
   value /= 2;
}
仅一夜美梦 2024-09-10 12:52:31

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

像(伪)的东西:

Init array
mask = 1
for (0 to BitCount):
  if Integer & mask
    array[] = pos
  mask << 1

If you want to get an array like that you'll likely need to loop the number of bits you want to check & the integer with a bit shifted 1 for each step.

Something like (pseudo):

Init array
mask = 1
for (0 to BitCount):
  if Integer & mask
    array[] = pos
  mask << 1
鹿港小镇 2024-09-10 12:52:31

位运算的变体类似于:

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] 未被使用。

A bit-crunching variation would be something like:

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

Note that since the bits are indexed from 1 as you requested, bits[0] is left unused.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文