ビットマスクのint値を保存-1価値のあるビットを抽出します

StackOverflow https://stackoverflow.com/questions/2932712

  •  05-10-2019
  •  | 
  •  

質問

特定の一連のビットに相当するINTに相当するものを計算し、それをメモリに保存しています。そこから、元のビットマスクからすべての1つの値ビットを決定したいと思います。例:

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

Javaでの実装のアイデア?

役に立ちましたか?

解決

の上 BitSet

使用する java.util.BitSet 保管するには、一連のビットを保存します。

Anから変換する方法は次のとおりです intBitSet, 、どのビットに基づいています int 設定されています:

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ベースのインデックス作成が使用されていることに注意してください。これは、BIT(および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)) 上記のスニペットで。ただし、この勧告に強くお勧めします。

関連する質問

他のヒント

少し気分を害するために、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;
}

C#実装を表示できます。Javaは非常に似ている必要があります。

int value = 33;
int index = 1;

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

   index++;
   value /= 2;
}

そのような配列を取得したい場合は、確認するビットの数をループする必要がある可能性があります & ステップごとに少しシフトした整数があります。

(pseudo)のようなもの:

Init array
mask = 1
for (0 to BitCount):
  if Integer & mask
    array[] = pos
  mask << 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] 未使用のままです。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top