1

このスクリプトを手動で入力して電卓を呼び出すと、次のようになります。

integer array[100];

次に、私の計算機は、vector<int>100個の要素を含む「配列」という名前のオブジェクトを作成します。

しかし、C++コードは独特です。たとえば、次のように入力して呼び出します。

integer array[100][100];
integer array[100][100][100];
//etc

次に、テンプレートvector<int>は違法です.... :(

とても腹立たしい!試しましたが、より良い解決策を見つけることができませんでした。誰かが私にいくつかのヒントを与えることができますか?

4

2 に答える 2

1

この回答は、一般的に異なるアプローチを対象としています。


任意にネストされた動的なサイズの配列をサポートするには(つまり、コンパイル時にネストされた配列の深さが制限されないように)、次のようなものを使用する必要があります。

スクリプト言語の変数のタイプは、次のいずれかである必要があります。

  • 整数
  • 浮く
  • (...サポートしたい他のプリミティブ型...)
  • これらのタイプの配列(配列を含む)
  • (...サポートしたい場合は連想マップなどの他のコンテナタイプ...)

これは通常、QtのBoostVariantやQVariantなどの「バリアント」タイプを使用して行われます。バリアント型は基本的に、型のセット(つまり、それらの1つ)と、実際に含まれている型を示す型記述子の和集合です。

したがって、この「任意のタイプ」が再び配列である場合にも、任意のタイプの配列を表すことができます。したがって、ネストされた配列の動的な深さをサポートできます。

「任意の型の配列」は、実際にはこのバリアント型のベクトルである必要があることに注意してください。Boost Variantの問題は、テンプレート引数として保持できるタイプを明示的にリストする必要があることです。これにより、再帰が発生します。

boost::variant<int, float, ..., std::vector<boost::variant<..., ...> > >
                                            ^^^^^^^^^^^^^^^^^^^^^^^^
                                                    recursion

Qtには、基本的にQtでサポートされているすべてのタイプを保持できるタイプQVariantがあります。QVariantはテンプレートクラスではないため、その型にはそのような再帰は含まれていません。同等のブーストタイプがあるかどうかはわかりませんが、疑わしいです。


スクリプトの実行中に配列のサイズを変更できない場合(または、サイズを変更する必要がある場合は、新しい配列を割り当てて内容をコピーできます)、より簡単な解決策があります。配列を1次元のベクトルに格納するだけでなく、スクリプト言語の配列の次元も別のベクトルに格納します。次に、次のようなインデックスメソッドを使用できます。

class ScriptArray {
    vector<int> dim;
    vector<int> elements;

    int getIndex(vector<int> indexList) const {
        int multiplicator = 1;
        int index = 0;
        for (int i = 0; i < dim.size(); ++i) {
            index = multiplicator * indexList[i];
            multiplicator *= dim[i];
        }
        return index;
    }
};

これは基本的に次の考え方の一般化です。1次元配列(10000要素)として表現する2次元配列(100 x 100要素)について考えてみます。元の配列()の任意のインデックスについて、x, yこれを内部配列()の1次元インデックスにマップできますx + 100 * y。3次元配列の場合、これには別の乗算(x + 100 * y + 100*100 * z)などが含まれます。

このソリューションと配列のサイズ変更の問題は、次元のサイズが変更されたときに要素が配列内で「移動」することです(特別な場合:この次元は「最も外側の」次元であるため、最後の次元)。したがって、サイズ変更時に配列が無効になるという事実に耐えることができるか、新しいサイズで新しい配列の内容をコピーするか、スペースを慎重に挿入/配列内のいくつかの要素を削除する複雑なサイズ変更メソッドを実装します。正しい場所。

于 2013-02-18T11:30:04.247 に答える
0

C++を使用して解析する独自の言語を作成したと想定しています。パーサーはinteger、識別子の前に型を見つけるため、変数を定義していることを認識しています。次に行う必要があるのは、正規変数または多次元配列を作成する必要があるかどうかを確認することです。

  • 角かっこ([])が存在しない場合->正規変数
  • 角かっこが存在する場合->ループを作成して、角かっこがいくつあるかをカウントします。次に、ネストされたベクトルを割り当てます。最終的なベクトルのみがタイプの要素を持ちますint

したがって、これを実装する最も簡単な方法は、配列を忘れて、角かっこが1つしかない多次元配列の特殊なケースと見なすことです。

于 2013-02-18T11:24:04.557 に答える