C++で各セルが2ビットだけの配列を作成したい。これを行う方法はありますか?
ビット配列を作成する方法はいくつかありますが、各セルに 1 ビットしか割り当てられません。
これを最初から書きたい場合:
おそらくすべてのビットセット実装が使用する基本的な考え方は、int[]
(または実際には他の整数型)を持ち、ビット単位の操作を使用して特定のビットを取得または設定することです。
オンラインでオープンソースの実装をたくさん見つけることができると思います。その一例が Java のBitSet (ここから入手可能) です。おそらくC++bitset
もどこかにあるでしょう。
ここでも同じ考え方が当てはまります。あるインデックスを 1 ビットにマッピングするのではなく、代わりに 2 ビットにマッピングします。
標準ライブラリ クラスを使用できる場合:
早速まとめたものがこちら。
基本的にビットの配列であるtwoBitSet
を拡張するクラスを作成しました。std::bitset
次に、提供されたインデックスの一部を の 2 ビットにマップしますbitset
。
twoBit
ヘルパー クラスもあり[]
ます。オペレーターを使用せずにデータを変更するのはやや困難です。
#include <iostream>
#include <bitset>
template <size_t N>
class twoBit
{
typedef typename std::bitset<2*N>::reference bitRef;
bitRef a, b;
public:
twoBit(bitRef a1, bitRef b1): a(a1), b(b1) {};
const twoBit &operator=(int i) { a = i%2; b = i/2; return *this; };
operator int() { return 2*b + a; };
};
template <size_t N>
class twoBitSet : private std::bitset<2*N>
{
typedef typename std::bitset<2*N>::reference bitRef;
public:
twoBit<N> operator[](int index)
{
bitRef b1 = std::bitset<2*N>::operator[](2*index);
bitRef b2 = std::bitset<2*N>::operator[](2*index + 1);
return twoBit<N>(b1, b2);
};
};
int main()
{
twoBitSet<32> bs;
bs[0] = 2;
bs[1] = 3;
bs[2] = 1;
bs[3] = 0;
std::cout << bs[0] << std::endl; // prints 2
std::cout << bs[1] << std::endl; // prints 3
std::cout << bs[2] << std::endl; // prints 1
std::cout << bs[3] << std::endl; // prints 0
}
現時点では明らかに基本的なものであり、[]
演算子の使用のみを許可し、範囲チェックはありません。
おそらく、2 つの[]
演算子関数 ( に類似bitset
) を作成するほうがよいでしょう。1 つはアクセサーであり、もう 1 つはtwoBit
オブジェクトを返します。
std::vector<bool>
あなたが探している専門分野があります。次に、2 つの連続する配列要素を 2 つの bool の 1 つの要素と見なすか、ループでインデックスを 2 ずつインクリメントするのが不快な場合は、このためのラッパー クラスを作成します。2 ビット変数でクラスを作成する際の問題は、C++ の最小変数サイズが 1 バイトであるため、依然として 8 ビット (1 バイト) を使用することです。
完全にカスタムの解決策は、文字 (8 ビット) の配列を作成し、シフト演算子を使用して各文字のすべてのビットを使用することです。ただし、値にアクセスするたびにシフトを解除する必要があるため、これは不必要に複雑になります(...そして、それがまさにstd::vector<bool>
特殊化の仕組みです)。