定数の大きなセクションを持つ大きな定数ビット配列に関連して、検討するテーブルを設計する別の方法を次に示します (正確なニーズがわからないため、役立つかどうかはわかりません)。
基数ツリーのようなものを考えてみましょう。説明を簡単にするために、get 関数を定義します。
#define TYP_CONST
#define TYP_ARRAY
struct node {
unsigned min;
unsigned max;
int typ;
union {
char *bits;
int constant;
} d;
struct node *left;
struct node *right;
}
struct bit_array {
unsigned length;
struct node *root;
}
int get(struct bit_array *b, unsigned ix)
{
struct node *n = b->root;
if (ix >= b->length)
return -1;
while (n) {
if (ix > n->max) {
n = n->right;
continue;
} else if (ix < n->min) {
n = n->left;
continue;
}
if (n->typ == TYP_CONST)
return n->d.constant;
ix -= n->min;
return !!(n->d.bits[ix/8] & (1 << ix%8));
}
return -1;
}
人間の言葉で言えば、ツリーを調べてビットを探します。すべてのノードはビットの範囲を担当し、範囲をバイナリ検索して目的の範囲を見つけます。
範囲が見つかったら、定数または配列の 2 つのオプションがあります。定数の場合は、定数を返すだけです (多くのメモリを節約できます)。配列の場合、ビット配列で配列ルックアップを行います。
O(1) の代わりに O(log n) のルックアップ時間が必要になりますが、それでも信じられないほど高速なはずです。
ここでの問題は、適切なデータ構造を設定するのが煩わしく、エラーが発生しやすいことです。しかし、あなたは配列が一定であると言ったので、それは問題ではないかもしれません.