2016-04-20 6 views
1

wir sagen, dass wir eine Matrix in einer matrix.txt-Datei haben, wie folgt gespeichert:C++ Matrix zu dynamischen 2D arrray

Image1

und wollen wir es in verwandeln:

Image 2

Nummer 8 (erste Zahl) bedeutet, wie groß 2D-Array sein wird. Danach ist es bedeutet: 1 bis 2 verbunden ist (Wert von Verbindung 1 ist, ist es immer 1 sein wird) 1 ist mit 8 3 bis 4

verbunden ist, und, wenn es in 2D dynamische Array umgewandelt, wir wollen der Wert 1 in ARRRAY 0,1 ... 0,7 ... 2,3 und so weiter (ich habe keine eckigen Klammern verwendet, da stackoverflow sie als Links liest).

int number; 
int **a = new int*[number]; 
for (int i = 0; i<number; i++) { 
    a[i] = new int[number]; 
} 
for (int i = 0; i<number; i++) { 
    delete[]a[i]; 
} 
    delete[]a; 

string line; 
ifstream myfile("matrix.txt"); 
if (myfile.is_open()) 
{ 
    getline(myfile, line); 
    istringstream(line)>> number; 


    while (getline(myfile, line)){ 
     cout << line << '\n'; 
     //HERE I SHOULD TURN THOSE NUMBERS INTO VALUES IN 2D ARRAY 
    } 
    myfile.close(); 
} 

Also meine Frage ist: Wie schalte ich diese Zahlen in Matrix in 2D-Array?

Danke

Antwort

2

Der einfache Weg, aber möglicherweise nicht den schnellsten Weg ist die Linie in ein std::stringstream zu schreiben, dann wieder aus dem String in Zeile, Spalte lesen, und Wertvariablen. Wenn Sie aus einer Datei lesen, sind die Kosten für das Lesen der Datei an erster Stelle in der Regel geringer als die Kosten für die Analyse der Datei. Wenn es in Ihrem Fall wichtig ist (und den Code zuerst profilieren, um sicherzustellen, dass dies der Fall ist), untersuchen Sie die Datei manuell. Das heißt, diese grundlegende Logik wird halten.

Von Thema, betrachten Sie die Verwendung einer Matrix-Klasse, um ein für Sie anstelle eines rohen 2D-Array zu verwalten. The matrix class here at isocppp.org is good and fast, sowie in einigen sehr guten allgemeinen Ratschlägen verpackt.

Der obige Code mit der isocpp Matrix wie folgt aussieht:

while (getline(myfile, line)){ 
    cout << line << '\n'; 
    std::stringstream linestream(line); 
    int row; 
    int column; 
    int value; 
    if (linestream >> row >> column >> value) 
    { 
     a(row-1,column-1) = value; 
     a(column-1,row-1) = value;// mirror 
    } 
    else 
    { 
     // handle file formatting error 
    } 
} 

fast identisch und viel einfacher zu benutzen, weil Sie den Speicher Sorgen machen müssen um die Array-Dimensionen nicht über die Verwaltung selbst, vorbei, oder ein bisschen schlechter Code (z. B. a[4] = 0;), der eine Zeile deines Arrays vernichtet.

Nachtrag

Dieser Code

int number; 
int **a = new int*[number]; 
for (int i = 0; i<number; i++) { 
    a[i] = new int[number]; 
} 
for (int i = 0; i<number; i++) { 
    delete[]a[i]; 
} 
delete[]a; 

hat zwei schwerwiegende Probleme:

  1. a mit number bemessen ist, und number noch nicht zugeordnet worden ist. number kann alles sein, von einer sofort tödlichen negativen Zahl (kann kein Array mit einer negativen Größe haben) bis hin zu einer potenziell fatalen riesigen Zahl (Ihr Computer hat 9.223.372.036.854.775.807 Quadratbytes an RAM? Ich glaube nicht.)
  2. Es löscht den Speicher sofort nach dem Zuweisen. Es ist eine gute Angewohnheit, den Speicher freizugeben, aber es ist am besten, den Speicher nach der Verwendung freizugeben, nicht vorher.

So:

// define `a` here 
string line; 
ifstream myfile("matrix.txt"); 
if (myfile.is_open()) 
{ 
    getline(myfile, line); 
    istringstream(line)>> number; 

    // allocate storage for `a` here 

    while (getline(myfile, line)){ 
     cout << line << '\n'; 
     //line reading code goes here 
    } 
    myfile.close(); 
} 
// delete `a` somewhere down here after it's been used. 
+0

Wenn es auf diese Weise versucht, bekomme ich einen Fehler, der besagt, dass a undefiniert ist. –

+0

Alles, was ich lieferte, war das '// HIER MUSS ICH DIESE ZAHLEN IN WERTE IN 2D-ARRAY EINSCHALTEN '' und die while-Schleife darum herum. Sie benötigen weiterhin den Rest Ihres Codes, um 'a' zu definieren und die Datei zu öffnen. – user4581301

+0

Es sei denn, Sie gehen für die Matrix-Version. In diesem Fall brauchst du Matrix a (Zahl, Zahl); Wenn du darüber nachdenkst, hast du einen bösen Fehler in der Definition deines Arrays. Eine Änderung vornehmen, um Ihnen zu helfen, das zu beheben. – user4581301

1

Ich schlage vor, Sie C++ Vektor aus der STL anstelle von 2d C-Array verwendet werden, die unsicher sind.

Sie tun könntest so etwas wie:

ifstream myfile("matrix.txt"); 

// Read matrix size 
size_t matrix_size = 0; myfile >> matrix_size; 

vector<vector<int> > matrix(matrix_size); 
for(size_t i=0; i < matrix.size(); ++i) matrix[i].resize(matrix_size); 
while(myfile.good()) 
{ 
    // Read row,col,val and set matrix value 
    int row=0, col=0, val=0; myfile >> row >> col >> val;  
    --row; --col; // Since your indices go from 1 to N 
    if(row < matrix_size && row >= 0 && col < matrix_size && col >= 0) { 
    matrix[row][col] = val; matrix[col][row] = val; 
    } 
} 
+0

Mehr als unsicher. Der Vektor ist viel einfacher zu verwenden, innerhalb des Programms herumzugehen und nach einem dynamisch zugewiesenen 2D-Array zu bereinigen. Das heißt, wenn Sie eine gute Leistung wünschen, verwenden Sie einen 1D-Vektor und fälschen die zweite Dimension mit 'row * number_columns + column' aus. Informieren Sie sich über die Auswirkungen von "Cache-Misses" auf ein Programm. – user4581301

+0

Wenn ich das Dateiformat von OP verstanden habe, scheint die endgültige Matrix symmetrisch zu sein, wobei nur der obere rechte Teil in der Datei gespeichert ist ... –

+0

Right @Bob__ Ich habe diesen Punkt verpasst. Die suboptimale Lösung besteht darin, denselben Wert in der Matrix [col] [row] hinzuzufügen. Eine bessere Lösung wäre die Verwendung einer Klasse für die Behandlung von symmetrischen Matrizen mit einem eindimensionalen Vektor und dem korrekten Operator [] für den Zugriff. – steiner