HOWTO · C++
Einen Vektor aus Vektoren in C++ erstellen
So erstellen, befüllen und ändern Sie einen Vektor aus Vektoren in C++.
Auf dieser Seite
Ein Vektor aus Vektoren speichert Zeilen als std::vector-Objekte in einem äußeren std::vector. Wenn die Anzahl der Zeilen und Spalten feststeht, erstellen Sie den äußeren Vektor mit der Zeilenanzahl und einem inneren Vektor, der Spaltenanzahl und Anfangswert enthält. Die Beispiele zeigen, wie Sie ein Raster mit festgelegten Abmessungen erstellen, mit Beispielwerten füllen und seine Elemente ändern. Dieses Muster eignet sich, wenn jede Zeile ein eigener Vektor sein soll und das Programm die Zahl der Zeilen oder Spalten bestimmt.
Einen Vektor aus Vektoren in C++ mit dem Größen- und Wert-Konstruktor erstellen
Der Größen- und Wert-Konstruktor macht sowohl die Abmessungen als auch die Anfangsinhalte ausdrücklich sichtbar. Zum Beispiel erstellt std::vector<std::vector<int>> grid(rows, std::vector<int>(columns, 0)); rows innere Vektoren mit jeweils columns Ganzzahlen, die mit null initialisiert sind. Der innere Vektor wird einmal als Wert konstruiert, mit dem die Zeilen des äußeren Vektors initialisiert werden. Das ist eine Konstruktion mit vorgegebener Größe und einem Anfangswert, nicht mit dem Standardkonstruktor. Die separate Form mit Standardkonstruktor wird in der Referenz zum Standardkonstruktor beschrieben.
Das folgende Beispiel erstellt vier Zeilen mit je sechs Ganzzahlen. Vektorindizes beginnen bei null: [2][2] wählt die dritte Zeile und die dritte Spalte aus. Die verschachtelten Aufrufe von .at() wählen die vierte Zeile und die vierte Spalte aus. .at() prüft jeden Index anhand der Größe des jeweiligen Vektors und meldet einen Zugriff außerhalb des gültigen Bereichs, wenn der Index kein Element bezeichnet. Der Indexzugriff mit eckigen Klammern ist knapp, wenn die Indizes bekanntermaßen gültig sind.
#include <iostream>
#include <vector>
int main() {
constexpr int LENGTH = 4;
constexpr int WIDTH = 6;
std::vector<std::vector<int>> grid(LENGTH, std::vector<int>(WIDTH, 0));
grid[2][2] = 12;
std::cout << grid[2][2] << '\n';
grid.at(3).at(3) = 99;
std::cout << grid[3][3] << '\n';
return 0;
}
12
99
Die Ausgabe ergibt sich direkt aus den beiden Zuweisungen. Verwenden Sie für Zeilen- und Spaltenindizes jeweils die passende Dimension: Der äußere Vektor wählt eine Zeile aus, und der innere Vektor dieser Zeile wählt eine Spalte aus. Wenn die Abmessungen nicht feststehen, können die Zeilenanzahl und die Größe jeder Zeile stattdessen aus Programmdaten stammen.
Mit der Funktion rand Beispielwerte in einen Vektor aus Vektoren in C++ einfügen
Sobald das Raster angelegt ist, können verschachtelte Schleifen jedes Element besuchen und ihm einen Beispielwert zuweisen. Das folgende Programm setzt den Startwert für rand anhand der aktuellen Uhrzeit und verwendet % 100, um Werte von 0 bis 99 zu erzeugen. Die ausgegebenen Werte können sich von Lauf zu Lauf unterscheiden; es gibt daher keine einzelne Ausgabe, die sich zum Abschreiben eignet. Das Beispiel bindet <cstdlib> für rand und srand sowie <ctime> für std::time ein.
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <vector>
int main() {
constexpr int LENGTH = 4;
constexpr int WIDTH = 6;
std::vector<std::vector<int>> grid(LENGTH, std::vector<int>(WIDTH, 0));
std::srand(static_cast<unsigned int>(std::time(nullptr)));
for (auto& row : grid) {
for (int& value : row) {
value = std::rand() % 100;
std::cout << value << ' ';
}
std::cout << '\n';
}
return 0;
}
Diese Werte dienen als Beispieldaten für Demonstrationen und einfache, nicht sensible Aufgaben. rand eignet sich nicht für kryptografische Anwendungen. Außerdem kann die Restwertbildung die Verteilung verzerren, sofern die Anzahl der möglichen Generatorwerte nicht ohne Rest durch 100 teilbar ist. Für Simulationen oder Anwendungscode mit höheren Anforderungen an die Verteilung sollten Sie einen passenden Zufallszahlengenerator verwenden, statt dieses kurze Beispiel als universellen Generator zu behandeln.
Jedes Element eines Vektors aus Vektoren in C++ mit verschachtelten bereichsbasierten Schleifen ändern
Eine bereichsbasierte Schleife durchläuft jede Zeile; eine darin verschachtelte Schleife besucht jede Ganzzahl dieser Zeile. In int& value sorgt & dafür, dass value eine Referenz auf das gespeicherte Element ist. Eine Zuweisung ändert dadurch den Wert im Vektor. Ohne Referenz wäre die Schleifenvariable eine Kopie, und ihre Änderung würde die gespeicherte Ganzzahl nicht ändern. Das Programm gibt ein Raster vor und nach der Multiplikation jedes Elements mit drei aus.
#include <iostream>
#include <vector>
void print(const std::vector<std::vector<int>>& grid) {
for (const auto& row : grid) {
for (int value : row) {
std::cout << value << ' ';
}
std::cout << '\n';
}
}
int main() {
std::vector<std::vector<int>> grid{{1, 2, 3}, {4, 5, 6}};
std::cout << "Before:\n";
print(grid);
for (auto& row : grid) {
for (int& value : row) {
value *= 3;
}
}
std::cout << "After:\n";
print(grid);
return 0;
}
Jeder innere Vektor verwaltet seine eigene Folge von Ganzzahlen; der äußere Vektor speichert die Zeilenvektoren. Die Ganzzahlen innerhalb einer Zeile liegen zusammenhängend im Speicher, die gesamte verschachtelte Struktur bildet jedoch keinen einzigen zusammenhängenden zweidimensionalen Speicherblock. Damit ist das Speicherlayout beschrieben; daraus folgt kein allgemeiner Geschwindigkeitsvergleich. Die Leistung hängt von der jeweiligen Operation und Arbeitslast ab. Ein verschachtelter Vektor ist nützlich, wenn Zeilen eigenständig sind oder reguläre Vektoroperationen benötigen. Wenn eine Aufgabe ausdrücklich einen einzigen zusammenhängenden Speicherblock erfordert, sollten Sie eine dafür ausgelegte Darstellung wählen.