Frage

Ich habe eine harte Zeit immer mein Kopf gewickelt, wie ein Vektor von Vektoren zu initialisieren.

typedef vector >>> Datacontainer;

Ich möchte dies entsprechen

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

die Elemente Adressierung ist nicht das Problem. Das sollte wie so einfach, wie etwas sein

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

Das Problem ist, dass ich es füllen muß mit Daten in aus, um aus einer Datei kommen, so dass aufeinanderfolgende Elemente müssen wie etwas platziert wird

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

Also brauche ich die V von V initialisieren vorher.

Am ich mich oder ist dies so einfach wie

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

Es scheint nicht, wie das funktionieren soll. Irgendwie sind die Top-Level-Vektoren zunächst initialisiert werden muss.

Jede Hilfe sehr geschätzt. Ich bin sicher, dass dies muss einfacher sein, als ich es mir vor.

War es hilfreich?

Lösung

  • Bitte Verwenden Sie keine verschachtelten Vektoren , wenn die Größe Ihrer Speicher bekannt ist, vor der Zeit , dh es gibt ein bestimmten Grund warum zB der erste Index muss der Größe 6, und wird sich nie ändern. verwendet nur eine einfache Anordnung. Noch besser wäre es, die Verwendung boost::array. Auf diese Weise erhalten Sie alle Vorteile eines einfachen Anordnung mit (speichern riesige Mengen an Speicherplatz, wenn Sie mehrdimensionale gehen), und die Vorteile eines echten Objektinstanziierung mit.

  • Bitte Verwenden Sie keine verschachtelten Vektoren , wenn Ihr Speicher muss rechteckigem , dh Sie können eine Größe oder mehrere der Dimensionen, aber jede „Reihe“ Muss sein die gleiche Länge an einem gewissen Punkt. Verwenden boost::multi_array. Auf diese Weise dokumentieren Sie „dieser Speicher ist rechteckig“, speichert große Mengen an Speicherplatz und immer noch die Fähigkeit erhalten, um die Größe, Vorteile ein reales Objekt mit, etc.

Die Sache std::vector ist, dass es (a) bedeutet, veränderbar und (b) sein muss über seinen Inhalt nicht im Geringsten kümmern, solange sie vom richtigen Typ sind. Dies bedeutet, dass, wenn Sie einen vector<vector<int> > haben, dann alle „Zeilenvektoren“ jeweils eine eigene Buchführung Informationen pflegen müssen, wie lange sie sind - auch wenn Sie erzwingen möchten, dass sie alle die gleiche Länge sind. Es bedeutet auch, dass sie alle separate Speicherzuordnungen verwalten, das die Leistung (Cache-Verhalten) verletzt, und Abfälle noch mehr Platz, weil, wie std::vector neu verteilt. boost::multi_array ist mit der Erwartung konzipiert, dass Sie es, um die Größe möchten, wird aber nicht ständig es (für einen 2-dimensionalen Array / faces Reihen, für eine 3-dimensionale Array / etc.) durch Anhängen von Elementen Ändern der Größe werden bis zum Ende . std::vector wird (potentiell) Abfall Raum entworfen, um sicherzustellen, dass der Betrieb nicht langsam ist. boost::multi_array ist so konzipiert, um Platz zu sparen und hält alles ordentlich im Speicher organisiert.

Das heißt :

Ja, Sie brauchen etwas zu tun, bevor Sie Index in den Vektor. std::vector wird nicht auf magische Weise bewirken, dass die Indizes in der Existenz Pop, weil Sie speichern dort etwas wollen. Dies ist jedoch leicht zu behandeln:

Sie können den Vektor mit der entsprechenden Menge von Nullen Standard initialisieren zuerst, und dann ersetzen, indem Sie den (size_t n, const T& value = T()) Konstruktor. Das heißt,

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

, weil ein "default-konstruiert" int den Wert 0 hat.

In Ihrem Fall müssen wir die Größe jeder Dimension angeben, durch Untervektoren zu schaffen, die in der entsprechenden Größe und lassen den Konstruktor sie kopieren. Das sieht aus wie:

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))));

Das heißt, eine unbenannte d1 der Größe 31 aufgebaut ist, die verwendet wird, um den Standard d2 zu initialisieren, die verwendet wird, um den Standard d3 zu initialisieren, die verwendet wird, result zu initialisieren.

Es gibt auch andere Ansätze, aber sie sind viel schwerfälliger, wenn Sie nur ein paar Nullen beginnen soll. Wenn Sie vorhaben, den gesamten Datensatz aus einer Datei zu lesen, aber:

  • Sie können .push_back() zu append auf einen Vektor verwenden. Machen Sie eine leere d1 kurz vor der am weitesten innen Schleife, in denen sie immer wieder .push_back() es zu füllen. Kurz nach der Schleife .push_back() Sie das Ergebnis auf den d2, die Sie kurz vor der nächsten innersten Schleife erstellt, und so weiter.

  • Sie können einen Vektor der Größe vorher mit .resize() und dann Index in sie normalerweise (bis zu dem Betrag, dass Sie die Größe zu verändern).

Andere Tipps

Sie würden wahrscheinlich eine Größe oder Reservespeicher setzen müssen

Könnte Sie eine for-each oder eine für das verschachtelte nennen würde

myVector.resize(x); //or size

auf jeder Ebene.

EDIT: Ich gebe zu diesem Code nicht elegant ist. Ich mag @Karl Antwort, die der richtige Weg zu gehen.

Dieser Code wird erstellt und getestet. Es gedruckt 208320 Nullen der erwartet wird, (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;
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top