0

C++ でリソースに依存しない機能を試しています。10000 レコードの配列を実装していますが、どのレコードも可能な値は 0、1、2 の 3 つしかありません。だから私は、10000インスタンスのメモリを3つすべて一緒に保存する代わりに、それぞれのインスタンスを1つだけ保存して論理的に管理する方法を考えていました。正確に実装する方法がわからない。

たとえば、私の配列は次のようになります。

{1, 0, 0, 1, 2, 1, 1, 1, 0, 2, 2, 0, 0, 0, 2,......}

10000 を超えるレコードも取得する可能性があります

4

2 に答える 2

3

1バイトあたり4つの値を持つ2500バイトの配列を作成できるようです(各値は2ビットかかります)。ビットシフト/マスキングを使用して任意の単一値にアクセスします。これは、値をグループ化するスキームよりも単純であり、アクセスに関してはより「配列のような」ものになると思います。もちろん、値をどのように処理する必要があるかわからないため、確実に言うのは難しいです。

実際には各バイトに5つの値を収めることができるので(3 5は243であるため)、必要なのはサイズ2000のバイト配列だけです...しかし、アクセスコードはやや扱いにくいでしょう。あなたが本当にそれを必要としない限り、私はこの余分な複雑さに抵抗します。

さらに、値が比較的まばらである場合(たとえば、ほとんどすべてが0で、1と2が数個しかない場合)、明らかにそれをより効率的に格納できます。

編集:さて、私は長い間C ++を実行していませんが、次のようになります。

// Entirely untested. Please test thoroughly, and make sure you understand it
// before using it.
int get_value(unsigned index)
{
    // TODO: Argument validation
    unsigned raw_index = index / 4;
    unsigned index_within_byte = (index % 4) * 2;

    return (array[raw_index] >> index_within_byte) & 3;
}

void set_value(unsigned index, int value)
{
    // TODO: Argument validation
    unsigned raw_index = index / 4;
    unsigned index_within_byte = (index % 4) * 2;

    int mask = 0xff ^ (3 << index_within_byte);
    array[raw_index] = (array[raw_index] & mask) | (value << index_within_byte);
}

編集:さらに考えてみると、バイトの配列uint32_tまたはuint64_tバイトの代わりに配列を作成し、各配列要素に16または32の「実際の」値を入れたい場合もあります。ほとんどのプロセッサでは、より効率的なメモリアクセスが可能になると思います。

于 2012-09-22T08:07:02.613 に答える
1

のベクトルを作成std::pair<int, int>し、firstペアのが0、1、または2をsecond含み、特定の要素が表示された回数を含むようにします。

だからあなたの例のために

{1、0、0、1、2、1、1、1、0、2、2、0、0、0、2、.............}

あなたはそれを次のように保存することができます

{<1、1>、<0、2>、<1、1>、<2、1>、<1、3>、<0、1>、<2、2>、<0、3>、< 2、...> ...}

連続した繰り返しがたくさんある場合、および直接アクセスする必要がない場合にのみ、それが良いことがわかります。

于 2012-09-22T08:13:27.887 に答える