2016-07-03 10 views
2

Also, ich habe eine Matrix wie folgt erstellt:Gibt es eine Möglichkeit, eine Matrix (Vektor von Vektoren) elegant mit STL zu füllen?

constexpr size_t row = 3, col = 5; 

std::vector<std::vector<int>> matrix(row, std::vector<int>(col)); 

Und ich versuche es die Eingabe mit Benutzern zu füllen. Dies ist die beste Lösung, die ich bisher habe:

for (size_t i = 0; i < matrix.size(); i++) 
{ 

    for (size_t j = 0; j < matrix[i].size(); j++) 
    { 
     std::cout << "Matrix[" << i << "][" << j << "] = "; 

     std::cin >> matrix[i][j]; 
    } 

    std::cout << "\n"; 
} 

Es sieht gut, funktioniert gut, aber es muss ein Weg sein, um diese mit STL zu erreichen, um diesen Code zu machen weniger sperrig.

Also ich frage nach Ihrer Hilfe beim Ausfüllen meiner Matrix mit Benutzereingaben. Jede Hilfe wird geschätzt!

Danke.

+0

Das sieht elegant aus, so wie man es erwarten würde. Sie können es weiter verschleiern, wenn Sie mit Tricks wie das Erzeugen einer Liste von Indizes für jede Größe und das Zippen der zwei, um (X, Y) -Paare zu erhalten, aber ich sehe nicht viel Hilfe darin sehen. Die einzige Verbesserung, die ich sehe, wäre, Vektor > in eine einzige Matrix-Klasse zu verpacken und damit zu arbeiten. –

+0

@AlexM. Oder Definieren von Operator >> für std :: vector und Verwenden von iStream_iterator –

Antwort

3

Wenn alles, was Sie nach sind, ist zu prettify it..then Sie so etwas wie tun:

constexpr size_t row = 3, col = 5; 
    constexpr size_t total = row * col; 
    std::vector<std::vector<int>> matrix(row, std::vector<int>(col)); 

    int j = -1; 
    for (int i = 0; i < total; i++) { 
    std::cin >> matrix[(i % col) ? j : ++j][i % col]; 
    } 

Und mit C++ 14:

std::for_each(std::begin(matrix), std::end(matrix), [](auto& v) mutable{ 
     for (auto& e : v) std::cin >> e; 
}); 

Sie auch die oben tun können, mit C++ 11 ohne die auto Art Abzug für Lambda.

+0

Wow, so kann 'std :: for_each' meinen Vektor ändern? Ich muss nur "mutable" vor geschweiften Klammern hinzufügen ... Cool, danke! –

0

Sie können std :: for_each versuchen, um Ihren Code kleiner zu machen. Auf diese Weise müssen Sie zwei Funktionen definieren (eine für die Zeilen, eine für die Spalten), um Ihre Matrix zu initialisieren.

+0

Nicht sicher, ob das funktioniert, 'std :: for_each' ist eine nicht-modifizierende Sequenzoperation. Ich kann immer nur eine Zeile nach Wert übergeben, was bedeutet, dass ich meine Matrix überhaupt nicht verändern werde. –

+0

Alles klar, es wird funktionieren. Ich bin einfach zu neu zu C++, ich wusste nicht über "veränderbare" Schlüsselwort ... –

0

Benutzereingabe ist nie einfach
Es gibt eine Menge, was schief gehen kann, und Sie müssen es sorgfältig immer behandeln.

Das Endziel sollte dann sein, die Eingabe für den Endbenutzer vernünftig zu gestalten, und nicht unbedingt "hübsch".

Zum Beispiel:

#include <algorithm> 
#include <cctype> 
#include <iostream> 
#include <iterator> 
#include <vector> 
#include <sstream> 
#include <string> 

struct matrix: public std::vector<std::vector<int>> { }; 

std::istream& operator >> (std::istream& ins, matrix& m) 
{ 
    std::string s; 
    std::size_t cols = 0; 

    // while input and not a blank line 
    while (std::getline(ins, s) and !s.empty()) 
    { 
    // scan one row from the input line 
    std::istringstream ss{ s }; 
    std::vector<int> row; 
    std::copy(std::istream_iterator<int>(ss), std::istream_iterator<int>(), std::back_inserter(row)); 

    // make sure that the source input stream fails if the intermediary fails 
    if (ss.fail()) 
    { 
     ins.setstate(std::ios::failbit); 
     return ins; 
    } 
    m.emplace_back(row); 

    // keep track of maximum number of columns 
    cols = std::max(cols,row.size()); 
    } 

    // make sure the matrix has the same number of columns in each row 
    for (auto& row : m) row.resize(cols); 
    return ins; 
} 

int main() 
{ 
    matrix m; 

    std::cout << "Enter the matrix, one row per line.\n" 
       "Press Enter twice when done:\n"; 
    std::cin >> m; 

    auto rows = m.size(); 
    auto cols = m.size() ? m[0].size() : 0; 
    std::cout << "Your matrix has " << rows << " rows and " << cols << " columns.\n"; 
} 

Offensichtlich ist dies bei weitem nicht hübsch. Aber es macht das Richtige.

Hoffe, das hilft.

+0

Bitte beschränken Sie sich auf die Herleitung von Standardcontainern. Es ist nicht das Richtige. – Arunmu

+0

Die _right_ Sache nach welchem ​​Standard? Du bist nur ein hirnloser Pedant - es ist nichts falsch daran, von einem Standard-Container zu erben, wenn du es nicht als etwas anderes behandeln willst, was es nicht ist. http: // Stapelüberlauf.com/questions/6806173/subclass-inherit-standardcontainers/7302165 # 7302165 Wenn es Ihnen so viel Unterschied macht, legen Sie es in einen Namespace oder wenden Sie private Vererbung oder verwenden Sie Komposition oder nur eine benannte Funktion erstellen. Oh, und nicht Standard-Container dynamisch zuweisen, OK? Es zeigt _bad design issues_ an. –

Verwandte Themen