C
DocShoe schrieb:
Du kannst das mit folgenden drei Zeilen Code erreichen:
void resize( std::vector<std::vector<int> >& arr, unsigned int Width, unsigned int Height )
{
// Schritt 1: äusseren Vektor auf Länge 1 setzen
arr.resize( 1 );
// Schritt 2: inneren Vektor (1. Element) auf Länge Width setzen
arr[0].resize( Width );
// Schritt 3: äusseren Vektor auf Länge Height setzen, neu hinzugefügte Elemente als Kopie des 1. Elements einfügen (haben damit die Länge Width)
arr.resize( Height, arr[0] );
};
Falls das dazu dienen soll, die Wahrscheinlichkeit des Fehlschlagens zu minimieren, ist das nicht sehr beeindruckend, ansonsten nur umständlich. Immerhin ist ein verschachtelter vector bestenfalls eine Krücke, so wie es ein nackter Doppelzeiger ist.
Neben anderen Problemen ist es zum Beispiel nicht möglich, vernünftig über alle Elemente des Arrays zu iterieren, so dass die direkte Anwendung von Standardalgorithmen ausgeschlossen ist.
void resize( std::vector<std::vector<int> >& arr, unsigned int Width, unsigned int Height )
{
vector<vector<int> >( Width, vector<int>( Height ) ).swap( arr );
};
erscheint sinnvoller, und ist nebenbei exceptionsicher. Beide Lösungen haben den Nachteil, dass der ursprüngliche Arrayinhalt nicht bewahrt wird (ok, in der ersten Variante schon, indem die Elemente der ersten Zeile dupliziert werden, was aber eher selten das Gewünschte sein dürfte).
Erstaunlich, dass wieder nicht auf die offensichtliche Lösung hingewiesen wird:
Da C++ keine mehrdimensionalen Arrays kennt, kann statt dessen ein Array mit der gewünschten Anzahl Elemente erzeugt werden, das dann in Verbindung mit einer Abbildung, die die Koordinaten in eine einzelne Zahl wandelt, verwendet wird. Im einfachsten Fall
class Labyrinth
{
public:
...
private:
char& at(unsigned x, unsigned y);
const char& at(unsigned x, unsigned y) const;
vector<char> lab_array; // Zeiger auf das Labyrinth
unsigned short mywidth; // Breite des Labyrinthes
unsigned short myheight; // Höhe des Labyrinthes
};
char& Labyrinth::at(unsigned x, unsigned y) { return lab_array[ y * mywidth + x ]; }
const char& Labyrinth::at(unsigned x, unsigned y) const { return lab_array[ y * mywidth + x ]; }
ein resize wird damit trivial über vectors resize realisiert.
Eleganter geht es mit boost MultiArray
#include "boost/multi_array.hpp"
class Labyrinth
{
typedef boost::multi_array_types::size_type size_type;
public:
Labyrinth() {}
Labyrinth(size_type width, size_type height)
: lab( boost::extents[width][height] )
{}
size_type GetWidth() const { return lab.shape()[0]; }
size_type GetHeight() const { return lab.shape()[1]; }
void resize(size_type width, size_type height) { lab.resize( boost::extents[width][height] ); }
char& at(size_type x, size_type y) { return lab[x][y]; }
const char& at(size_type x, size_type y) const { return lab[x][y]; }
private:
boost::multi_array<char,2> lab;
};