2

Cプログラミング言語についてです。

多数の 2D 配列 ( sizes are not fixed) があります。次の例を検討してください。

bool sym_a[][]={{...},{...},...};  //consider these are initialized properly
bool sym_b[][]={{...},{...},...};
...
bool sym_z[][]={{...},{...},...};
bool sym_0[][]={{...},{...},...};
bool sym_1[][]={{...},{...},...};
...
bool sym_9[][]={{...},{...},...};
...

命名規則に注意してください。すべての名前は似ています。配列名の最後の文字のみが変更されます (複数の文字を使用できる場合はより適切ですが、それは重要ではありません)。

さて、これで関数ができました。渡された引数に従って、これらの 2D 配列の 1 つを選択します。次に、選択したアレイでいくつかのタスクを実行します。タスクは一般的なものであり、選択した配列のみが変更されることに注意してください。

たとえば、私が現在考えていることによると、ええ、スイッチケースでは、次のように機能を実装できます。

void doStuff(char letter){
    switch(letter){
        case 'a':
            sym_a[0][0]=1;  //just for demonstration :D
        break;
        case 'b':
            sym_b[0][0]=1;  //same thing, only the character 'a' changed to 'b'
        break;
        ...
        case 'z':
            sym_z[0][0]=1;
        break;
        case '0':
            sym_0[0][0]=1;
        break;
        case '1':
            sym_1[0][0]=1;
        break;
        ...
        ...
    }    
}

しかし、もっと良い方法があるはずです。そのような配列が1000個ある場合、そのようなケースを1000個書く必要がありますか?? いずれの場合も、内容はまったく同じです。変数名の 1 文字だけが変更されます。

文字列連結のようなものがあればいいのですが。

#define conc(a,b) a ## b

次にconc(sym_,a)を表しsym_aます。しかし、それをここで直接適用することはできません。の右側の引数に正確な文字を渡すことができないためconc(a,b)、目的の文字を含む変数のみを渡すことができます。

void doStuff(char letter){
    conc(sym_,letter)[0][0]=1;
}

conc(sym_,letter)を与えsym_letterます。sym_しかし、文字変数の内容と連結する必要がありますletter

たとえば、私がdoStuff('b');それらsym_bを呼び出す場合は、代わりにsym_letter.

私の要件が明確であることを願っています。これはかなり単純に思えますが、これを取り除く方法は思いつきません。2D 配列のサイズ (行/列の数) は固定されていないことに注意してください。それ以外の場合は、3D 配列を使用できたはずです。

どんな考えでも大歓迎です。

4

3 に答える 3

2

多数の静的配列があるため、それらにアクセスするための多数の条件付きになるのはおそらく自然な拡張です。

文字コードを配列にマップする追加の静的配列を定義できます。

static const struct {
  char* lookup_code;
  bool **array;
} char_code_lookup[] = {
    { .lookup_code = "a", sym_a },
    { .lookup_code = "b", sym_b },
    /* ... */
    { .lookup_code = NULL, NULL }, /* Terminator */
};

次にdoStuff、関数は配列をスキャンして、静的に定義された配列と一致する適切なルックアップ コードを探します。

ちょっとしたマクロ マジックを使えば、静的配列と静的ルックアップ配列の両方を一緒に生成して重複を減らすことができますが、上記の方法の方がおそらく読みやすいでしょう。

または、 を使用して配列を動的に割り当てるmallocと同時に、実行時に配列が作成されるときにルックアップ コードを関連付けることもできます。

于 2013-03-28T05:08:19.963 に答える
1

このようなものは役に立ちますか?[ここに C++ が含まれている場合は申し訳ありません。]

bool** sym_a;
bool** sym_b ;
bool** sym_z;
bool** sym_0;
bool** sym_1;
bool** sym_9 ;


unsigned lowestEntry = 'a';
unsigned highestEntry = '9';
const unsigned numEntries = highestEntry - lowestEntry;

size_t size = sizeof(bool**)* numEntries;

bool*** lookup = (bool***)malloc(size); 

#define conc(a,b) a ## b
#define index(a) #a[0]-'a'
#define add(a) lookup[index(a)] = conc(sym_,a)

void init()
{
    memset(lookup, 0, size);
     add(a);
     add(b);
     add(z);
     add(9);
     add(k); // does not compile, sym_k not defined.
}

bool** findSymbolTable(char val)
{
    return lookup[val - lowestEntry];
}
于 2013-03-28T05:31:01.563 に答える
1

大きな int 配列を割り当て、それを他の変数用に分割します。

例えば。

intデータ[2600];

sym_a の最初の 100 個の整数、sym_b の次の 100 個などになります。これらの配列には、8 * 100* 4 個のブール値を格納できます。

sym_p[x][y] にアクセスするには、合計 R 行と C 列があると言うでしょう:

int * start = データ + (ASCIValue(p) - ASCIValue(a)) * 100;

最初からビット番号 (C * x + y) を読み書きする必要があります。

于 2013-03-28T05:48:16.197 に答える