【问题标题】:Storing int value of bitmask - extract 1 valued bits存储位掩码的 int 值 - 提取 1 值位
【发布时间】:2010-05-28 21:41:22
【问题描述】:

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

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

Java 实现的想法?

【问题讨论】:

    标签: java bitmask


    【解决方案1】:

    开启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 开始的索引,则可以在上述 sn-ps 中使用 bs.set(k+1);(1 &lt;&lt; (k-1))。但是,我强烈反对这个建议。

    相关问题

    【讨论】:

      【解决方案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;
      }
      

      【讨论】:

        【解决方案3】:

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

        整数值 = 33; 整数索引 = 1; 而(值> 0) { 如果 ((值 % 2) == 1) Console.WriteLine(index); 索引++; 值/= 2; }

        【讨论】:

        • Console.WriteLine 替换为 System.out.println 和瞧 :-)
        【解决方案4】:

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

        类似(伪):

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

        【讨论】:

          【解决方案5】:

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

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2023-03-15
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多