9

ベクトルのベクトルを初期化する方法に頭を悩ませるのに苦労しています。

typedef vector< vector < vector < vector< float > > > > DataContainer;

これに準じてほしい

level_1 (2 elements/vectors)
   level_2 (7 elements/vectors)
      level_3 (480 elements/vectors)
         level_4 (31 elements of float)

要素に対処することは問題ではありません。それは次のような単純なものでなければなりません

dc[0][1][2][3];

問題は、連続するアイテムを次のように配置する必要があるように、ファイルから順不同で入ってくるデータでそれを埋める必要があることです

dc[0][3][230][22];
dc[1][3][110][6]; //...etc

そのため、事前に V の V を初期化する必要があります。

私は自分自身を気まぐれにしていますか、それともこれは簡単ですか

for 0..1
    for 0..6
        for 0..479
           for 0..30
               dc[i][j][k][l] = 0.0;

それはうまくいかないようです。どういうわけか、最上位のベクトルを最初に初期化する必要があります。

どんな助けでも感謝します。これは私が想像しているよりも簡単でなければならないと確信しています。

4

3 に答える 3

21
  • ストレージのサイズが事前にわかっている場合は、ネストされたベクトルを使用しないでください。たとえば、最初のインデックスのサイズを 6 にする必要があり、決して変更されないなど、特定の理由がある場合です。単純な配列を使用してください。いっそのこと、使用します。そうすれば、単純な配列を持つことのすべての利点 (多次元になると大量のスペースを節約する) と、実際のオブジェクトのインスタンス化を持つことの利点が得られます。boost::array

  • ストレージが長方形でなければならない場合は、ネストされたベクトルを使用しないでください。つまり、1 つ以上の寸法のサイズを変更する可能性がありますが、すべての「行」はある時点で同じ長さでなければなりません。を使用します。そうすれば、「このストレージは長方形です」と文書化し、大量のスペースを節約しながら、サイズ変更機能、実際のオブジェクトを持つ利点などを得ることができます。boost::multi_array

重要なstd::vectorのは、(a) サイズ変更可能であり、(b) 正しい型である限り、その内容を少しも気にしないことです。これは、 がある場合vector<vector<int> >、すべての「行ベクトル」は、すべて同じ長さであることを強制したい場合でも、それらの長さに関する独自の簿記情報を維持する必要があることを意味します。また、それらはすべて個別のメモリ割り当てを管理することを意味し、パフォーマンス (キャッシュ動作) を損ない、std::vector再割り当て方法のためにさらに多くのスペースを浪費します。boost::multi_arrayサイズを変更したいかもしれないことを期待して設計されていますが、要素 (行、2 次元配列の場合は面、3 次元配列の場合は面など) を最後に追加してサイズを常に変更することはありません。std::vector動作が遅くならないように (潜在的に) スペースを浪費するように設計されています。boost::multi_arrayは、スペースを節約し、すべてをメモリ内できちんと整理できるように設計されています。

それは言った

はい、ベクトルにインデックスを付ける前に何かをする必要があります。std::vectorそこに何かを保存したいので、魔法のようにインデックスが存在するようになることはありません。ただし、これは簡単に処理できます。

最初に適切な量のゼロでベクトルをデフォルトで初期化してから、(size_t n, const T& value = T())コンストラクターを使用してそれらを置き換えることができます。あれは、

std::vector<int> foo(10); // makes a vector of 10 ints, each of which is 0

「デフォルトで構築された」int の値は 0 であるためです。

あなたの場合、適切なサイズのサブベクトルを作成し、コンストラクターにそれらをコピーさせることにより、各次元のサイズを指定する必要があります。これは次のようになります。

typedef vector<float> d1;
typedef vector<d1> d2;
typedef vector<d2> d3;
typedef vector<d3> d4;
d4 result(2, d3(7, d2(480, d1(31))));

つまり、名前のないd1はサイズ 31 で構築され、 defaultを初期化するために使用されます。これはd2、 default を初期化するためにd3使用されますresult

他のアプローチもありますが、たくさんのゼロを開始したいだけの場合は、はるかに扱いにくいです。ただし、ファイルからデータ セット全体を読み取る場合は、次のようにします。

  • .push_back()ベクターに追加するために使用できます。d1最も内側のループの直前に空を作り、繰り返し.push_back()て埋めます。ループの直後に、次の最も内側のループの直前に作成.push_back()した に結果を追加します。d2

  • を使用して事前にベクトルのサイズを変更し、.resize()通常どおり (サイズ変更した量まで) インデックスを付けることができます。

于 2010-12-01T00:37:24.863 に答える
2

編集: このコードが洗練されていないことは認めます。正しい方法である@Karlの回答が好きです。

このコードはコンパイルおよびテストされています。予想される208320個のゼロを出力しました(2 * 7 * 480 * 31)

#include <iostream>
#include <vector>

using namespace std;

typedef vector< vector < vector < vector< float > > > > DataContainer;

int main()
{
    const int LEVEL1_SIZE = 2;
    const int LEVEL2_SIZE = 7;
    const int LEVEL3_SIZE = 480;
    const int LEVEL4_SIZE = 31;

    DataContainer dc;

    dc.resize(LEVEL1_SIZE);
    for (int i = 0; i < LEVEL1_SIZE; ++i) {
        dc[i].resize(LEVEL2_SIZE);
        for (int j = 0; j < LEVEL2_SIZE; ++j) {
            dc[i][j].resize(LEVEL3_SIZE);
            for (int k = 0; k < LEVEL3_SIZE; ++k) {
                dc[i][j][k].resize(LEVEL4_SIZE);
            }
        }
    }

    for (int i = 0; i < LEVEL1_SIZE; ++i) {
        for (int j = 0; j < LEVEL2_SIZE; ++j) {
            for (int k = 0; k < LEVEL3_SIZE; ++k) {
                for (int l = 0; l < LEVEL4_SIZE; ++l) {
                    dc[i][j][k][l] = 0.0;
                }
            }
        }
    }

    for (int i = 0; i < LEVEL1_SIZE; ++i) {
        for (int j = 0; j < LEVEL2_SIZE; ++j) {
            for (int k = 0; k < LEVEL3_SIZE; ++k) {
                for (int l = 0; l < LEVEL4_SIZE; ++l) {
                    cout << dc[i][j][k][l] << " ";
                }
            }
        }
    }

    cout << endl;
    return 0;
}
于 2010-12-01T00:46:21.760 に答える
2

おそらく、サイズを設定するか、メモリを予約する必要があります

for-each またはネストされた for を実行できますか

myVector.resize(x); //or size

各レベルで。

于 2010-12-01T00:19:34.397 に答える