Matrix - Spalten vertauschen



  • Alter Titel: Matrix als Argument - Anzahl der Zeilen und Spalten?

    Hallo,

    bin gerade dabei mir einen LGS-Solver zu basteln, der den Gauss-Jordan-Algorithmus benutzt. Wie auch immer ... jedenfalls habe ich mir eine float-Matrix folgendermaßen erstellt (z und s sind bekannt):

    float** Matrix = CreateMatrix(z, s);
    
    //CreateMatrix()-Declaration
    float** CreateMatrix(int iRows, int iColumns)
    {
    	float** Matrix;
    	Matrix = new float* [iRows];
    
    	for(int i = 0; i < iRows; i++)
    	{
    		Matrix[i] = new float [iColumns];
    	}
    
    	return Matrix;
    }
    

    Jetzt habe ich mir natürlich schon einige Funktionen gebastelt um die Matrix zu manipulieren usw. Dabei habe ich bisher immer die Matrix selbst und die Anzahl der Spalten und/oder Zeilen als Argumente übergeben. Beispielsweise bei dieser Funktion, welche den Spaß wieder aufräumt:

    DeleteMatrix(Matrix, z);
    
    //DeleteMatrix()-Declaration
    void DeleteMatrix(float** Matrix, int iRows)
    {
    	for(int i = 0; i < iRows; i++)
    	{
    		delete[] Matrix[i];
    	}
    	delete[] Matrix;
    
    	return;
    }
    

    Da das auf Dauer recht nervig ist, wollte ich das jetzt ändern. Natürlich könnte man die Matrix in eine Struktur packen in der außerdem noch die Anzahl der Spalten und Zeilen gespeichert wird und dann immer die Struktur übergeben, da spricht sicher auch nix dagegen (habe ich hier im Forum schon gesehen (SuFu)). Trotzdem frage ich mich, ob es auch anders geht, mit sizeof() oder so vielleicht??? Ich wüsste jetzt nicht, wie.

    MfG dust



  • std::vector



  • ok, hab bei google gleich was Gutes gefunden zu "vector"... schau ich mir mal an ...

    ich formuliere meine Frage um: Kann ich mittels sizeof() die Anzahl der Zeilen bzw. Spalten (sprich: Array-Range) herausfinden?



  • dust schrieb:

    ich formuliere meine Frage um: Kann ich mittels sizeof() die Anzahl der Zeilen bzw. Spalten (sprich: Array-Range) herausfinden?

    Nicht bei deinen dynamisch allokierten Arrays, denn das sind im Grunde nur Zeiger.



  • Danke euch!



  • Hallo, ich habe folgende Funktion geschrieben, die 2 Spalten einer Matrix vertauschen soll, allerdings bekomme ich in der 8. Zeile (temp = ...) einen Fehler während der Laufzeit, aus dem Debuggen werde ich nicht schlau. Was mache ich falsch? Denkfehler oder gehe ich mit den Pointern falsch um?

    //Aufruf in main(), natürlich hat die Matrix >= 3 Zeilen und die erste und zweite Spalte existieren auch
    SwapColumns(&Matrix, 3, 1, 2);
    
    //SwapColumns()-Declaration
    void SwapColumns(float*** Matrix, int iRows, int i1stColumn, int i2ndColumn)
    {
    	float temp;
    
    	for (int i = 0; i < iRows; i++)
    	{
    		temp = *(Matrix[i][i1stColumn - 1]);
    		*(Matrix[i][i1stColumn - 1]) = *(Matrix[i][i2ndColumn - 1]);
    		*(Matrix[i][i2ndColumn - 1]) = temp;
    	}
    	return;
    }
    


  • 👍 push



  • a) Benutze std::swap für den Dreieckstausch
    b) übergib ein float** und greife mit Matrix[i][j] auf die Elemente zu. Ansonsten: (*Matrix)[i][j]. Den Pointer-Kram solltest Du nochmal genau anschauen. Besser ist möglichst wenig mit blanken Pointern zu fummeln 😉 .
    c) return ohne Rückgabewert sparst Du Dir besser am Ende einer Funktion. Ist unnötig.
    d) weitere Tips zu Deinem Vorhaben: Du könntest eine weitere Indirektion über eine Permutation einführen und Dir damit das umkopieren komplett sparen. Und ausserdem kannst Du den Speicher auch am Stück anfordern und Dir die Positionen umrechnen bzw. über ein Proxy-Objekt einen operator[][] "bauen". Erstmal würde ich den Matrix-Kram sowieso in eine Klasse packen.
    e) Du könntest die Matrix auch spaltenweise anfordern und dann einfach mit std::swap(Matrix[i], Matrix[j]) die Spalten tauschen, indem Du einfach die Pointer "swappst".

    Zu Deinem Code oben:

    void SwapColumns(float*** Matrix, int iRows, int i1stColumn, int i2ndColumn) 
    {    
        for (int i = 0; i < iRows; i++) 
            std::swap((*Matrix)[i][i1stColumn - 1], (*Matrix)[i][i2ndColumn - 1]); 
    }
    

    sollte eigentlich funktionieren 😉 . Du musst evtl. noch "#include <algorithm>" in den Dateikopf einfügen.

    Das hier

    void SwapColumns(float** Matrix, int iRows, int i1stColumn, int i2ndColumn) 
    {    
        for (int i = 0; i < iRows; i++) 
            std::swap(Matrix[i][i1stColumn], Matrix[i][i2ndColumn]); 
    }
    

    finde ich persönlich aber besser. Der Dreifach-Pointer ist hier unnötig und die Indizierung in C++ beginnt im Gegensatz zu Fortran, Matlab und Co. mit 0. Daran halten sich auch die meisten darauf aufbauenden Libraries. Aber das ist eher Geschmackssache. Manche Libraries lassen einem auch die Wahl ob nun 0 oder 1 das erste Element in einem Array-Datentyp sein soll.


Anmelden zum Antworten