Mehrdimensonaler Vektor füllen



  • Hi,

    ich würde gernen einen mehrdimensonalen Vektor füllen.
    Beispiel ist mit Vektor und Array, wobei Vektor so nicht klappt.

    vector <vector <double> > arc2;
    double arc[maxNodes][maxNodes];
    
    		for (int i=0;i<maxNodes;i++)		
    			for (int y=0;y<maxNodes;y++)
    			{
    				arc[i][y]=noArc;
    				arc2[i][y].push_back(noArc);
    			}
    

    Weiß einer wie genau die passende Syntaxe dafür ist?



  • arc2[i][y].push_back(noArc)

    arc2 ist vom typ vector< vector<double> >, also ist arc2[i] vom typ vector<double> und arc2[i][y] ist vom typ double. Ein double hat keine methode push_back. Wann legst du ueberhaupt die Vectoren im aeusseren vector an? Du greifst einfach darauf mit dem arc2[i] zu, ohne sie jemals erzeugt zu haben...



  • Heinzelotto schrieb:

    Wann legst du ueberhaupt die Vectoren im aeusseren vector an? Du greifst einfach darauf mit dem arc2[i] zu, ohne sie jemals erzeugt zu haben...

    Sry verstehe das nicht so ganz.
    Könntest du das an einem Beispiel illustrieren?



  • // Im Konstruktor wird die Anzahl der initialen Elemente angegeben
    vector <vector <double> > arc2( maxNodes, vector<double>(maxNodes) );
    
    for (int i=0;i<maxNodes;i++)       
        for (int y=0;y<maxNodes;y++)
            arc2[i][y] = noArc;
    
    // Oder um gleich alles mit "noArc" zu initialisieren:
    vector <vector <double> > arc2( maxNodes, vector<double>(maxNodes,noArc) );
    
    // Oder ohne vorher die 'vector'en auf die richtige Größe zu setzen:
    vector <vector <double> > arc2;
    for (int i=0;i<maxNodes;i++)
    {
        std::vector<double> v;
        for (int y=0;y<maxNodes;y++)
            v.push_back( noArc;
        arc2.push_back( v );
    }
    


  • Danke für das Beispiel.

    ich habe mich für folgendes entschieden:

    vector <vector <double> > arc2;
    for (int i=0;i<maxNodes;i++)
    {
        std::vector<double> v;
        for (int y=0;y<maxNodes;y++)
            v.push_back( noArc;
        arc2.push_back( v );
    }
    

    Wie kann ich nun nach dem ich es erstellt habe, alle Elemente löschen?
    Wenn ich z.B im Programm maxNodes ändere, dann muss ich vorher den vector leeren, bevor er wieder neu aufgebaut wird.



  • Lies doch die Referenz zu std::vector auf www.cplusplus.com. Die Funktion, die den Vector leert, hat einen recht treffenden Namen.



  • Krikus schrieb:

    Wie kann ich nun nach dem ich es erstellt habe, alle Elemente löschen?

    arc2.clear(); // schmeisst alles weg ==> 0x0 Matrix
    

    Krikus schrieb:

    Wenn ich z.B im Programm maxNodes ändere, dann muss ich vorher den vector leeren, bevor er wieder neu aufgebaut wird.

    Nein, musst Du nicht. Du kannst auch auf den Vektoren resize aufrufen. Damit kannst Du dann noch etwas Zeit sparen, weil die Vektoren im Vektor ihren reservierten Speicher wiederverwenden können.

    Statt überall im Code, wo du diesen "2D-Vektor" benutzt, Dich mit der Verwaltung rumzuärgern, könntest Du dafür auch eine eigene Klasse schreiben, die das ganz alleine regelt, zB "raster2d" (siehe http://de.wikipedia.org/wiki/Datenkapselung_(Programmierung)). Dann hast Du im Programm nur eine Stelle, die für die interne Verwaltung eines 2D-Arrays zuständig ist. Vorteil: Du kannst die Details der Implementierung später ändern, ohne dass Dein restliches Programm angepasst werden muss -- sofert die Schnittstelle die gleiche bleibt.

    class raster2d
    {
    public:
      raster2d(int zeilen, int spalten, double default_wert = 0)
      { reset(zeilen,spalten,default_wert); }
    
      void reset(int zeilen, int spalten, double default_wert = 0);
    
      double operator()(int zeile, int spalte) const;
      double& operator()(int zeile, int spalte);
    
      .....
    
    private:
      std::vector<std::vector<double> > elements_;
      // alternativ std::vector<double> elements_;
    };
    
    .....
    

    Gruß,
    SP



  • Sebastian Pizer schrieb:

    Krikus schrieb:

    Wenn ich z.B im Programm maxNodes ändere, dann muss ich vorher den vector leeren, bevor er wieder neu aufgebaut wird.

    Nein, musst Du nicht. Du kannst auch auf den Vektoren resize aufrufen. Damit kannst Du dann noch etwas Zeit sparen, weil die Vektoren im Vektor ihren reservierten Speicher wiederverwenden können.

    Hm, ich habe ihn so verstanden, dass ein Leeren semantisch wirklich erforderlich ist.

    Falls dem wirklich so ist, solltest du bedenken, dass ein resize() beim Vergrössern die alten Elemente unverändert lässt. Abgesehen davon bleibt der Speicher von std::vector auch nach einem clear() -Aufruf erhalten, diesbezüglich hast du also keinen Unterschied.



  • Nexus schrieb:

    Hm, ich habe ihn so verstanden, dass ein Leeren semantisch wirklich erforderlich ist.

    Falls dem wirklich so ist, solltest du bedenken, dass ein resize() beim Vergrössern die alten Elemente unverändert lässt.

    Das müsste man natürlich behandeln. Für die "inneren" Vektoren würd ich einfach clear gefolgt von resize(neue_groesse,default_wert) aufrufen.

    Nexus schrieb:

    Abgesehen davon bleibt der Speicher von std::vector auch nach einem clear() -Aufruf erhalten, diesbezüglich hast du also keinen Unterschied.

    Beim "Haupt-Vektor" ist das resize schon sinvoller. Wenn Du bei dem nämlich clear() aufrufst werden seine Elemente zerstört, was in diesem Fall ja Vektoren sind, die sich ggf Speicher organisiert hatten. Ich würde also die ersten min(maxNodes_alt,maxNodes_neu) "inneren" Vektoren einzeln anpassen (mit clear + resize ) und dann den "äußeren" Vektor per resize vergrößern/verkleinern.

    Gruß,
    SP



  • Sebastian Pizer schrieb:

    Ich würde...

    ...vor allen Dingen eine extra Klasse dafür schreiben und nur einen einzigen Vektor als privates Element anlegen. Es kommt im Endeffekt darauf an, wass das Ding können muss. Eine lineare Addressierung aller Elemente (i+j*zeilen) hat in manchen Situationen Vorteile.

    Gruß,
    SP


Anmelden zum Antworten