Anfängerfrage zu mehrdimensionalen Arrays


  • Mod

    Besser, aber offensichtlich noch nicht richtig. Wobei es hilfreich wäre, wenn du Probleme genauer beschreiben könntest als "nur Mist". Denn mit einer guten Beschreibung kann man gezielter nach Problemen suchen, anstatt deinen ganzen Code durchlesen zu müssen.
    Zurück zum Thema: Da ist immer noch ein Unterschied zwischen den beiden Blöcken für die Zeilen und die Spalten. Die Struktur ist jetzt zwar gleich, aber du hast beim Spiegeln der Indizes eine Sache vergessen (oder noch genauer: Eine Sache hast du nur halb gespiegelt). Schau noch einmal ganz genau hin auf die beiden Blöcke: Was ist gleich, was hast du geändert, und passt das alles zusammen?



  • Danke dir Sepp dass du dir die Zeit nimmst, ja wenn man ganz am Anfang steht ist es oft zäh. Und du hast Recht Mist müsste man genauer definieren. Ok beim Ergebnis sind die folgenden Zeilenergebnisse zu erwarten: 0.3 ; 0.7 und 1.1
    das wird auch richtig ausgegeben. Bei den Spalten wären die Ergebnisse 0.9 und 1.2 zu erwarten als Resultat bekomme ich 0.4 und 0.6 also kein richtiges Ergebnis.

    Weil du sagtest ich habe den Block nur halb umgeschrieben habe ich gerade nochmals versucht diesen anzupassen

    double sums2[2] = { 0.0, 0.0 };
    	for (int i = 0; i < 3; i++)
    	{
    		double sum2 = 0.0;
    
    		for (int j = 0; j < 2; j++)
    		{
    			sum2 += M[j][i];
    		}
    
    		sums2[i] = sum2;
    	}
    	for (int j = 0; j < 2; j++)
    	{
    		cout << endl << "In Column " << j << " is the sum: " << sums2[j];
    	}
    

    Ergebnis bleibt das gleiche, also der Denkfehler ist noch da wobei ich inzwischen wie ein Brett vor dem Kopf und das Gef+hl habe gar nix mehr zu verstehen.



  • @montanistikus1 sagte in Anfängerfrage zu mehrdimensionalen Arrays:

    habe den Block nur halb umgeschrieben

    Poste trotzdem kompletten Code. Niemand hat Lust sich das zusammenszustückeln. Du kannst Deinen Beitrag im Nachhinein bearbeiten. Den Menüpunkt "Bearbeiten" findest Du hinter dem Drei-Punkte-Menü rechts unter Deinem Beitrag.



  • @montanistikus1: Da dein 2-dimensionales Array als M[3][2] definiert ist, darfst du mittels M[i][j] nur mit passenden Indexwerten darauf zugreifen (also für i nur Werte von 0 bis 2 und für j nur von 0 bis 1) - dies mußt du also bei deinen Schleifen beachten (analog gilt diese Aussage natürlich dann für den Zugriff mittels M[j][i], nur eben umgekehrt).



  • lieber Th69

    Ich sehe da in meinen Schleifen keinen Fehler habe i < 3 und j < 2 gesetzt also wird ohnehin nur der von dir genannte Wertebereich durchlaufen.

    @ sword

    Du hast recht habe den gesamten Code aber eh oben gepostet habe nur im letzten Beitrag nur mehr den zweiten Funktionsblock gepostet da laut Sepp ja eigentlich dort drinnen der Fehler liegt.
    Denn der Block der die Zeilensumme ausgibt der funktioniert ja tadellos



  • Um Spalten- statt Zeilensummen zu bilden, mußt du die Schleifen vertauschen, aber den Zugriff auf das Array beibehalten.
    Du greifst aber mittels M[j][i] zu - und nicht mittels M[i][j]!



  • Vielen Dank Th jetzt erkenne ich was für ein Volltro... ich war klar einfach die Schleifen umtauschen und den Parameter.
    Ich glaub jetzt verstehe ich es, hab das ganze jetzt so umgebaut und jetzt endlich tut das Programm so wie es sein soll.
    Vielen Dank jetzt ists mir auch klar geworden wieso

    #include <iostream>
    
    using std::cout;
    using std::endl;
    using std::cin;
    
    int main()
    {
    	// Matrix M 3x2, reelle (double)
    	double M[3][2] =
    	{
    		{0.1, 0.2},
    		{0.3, 0.4},
    		{0.5, 0.6}
    	};
    	double sums[3] = { 0.0, 0.0, 0.0 };
    	for (int i = 0; i < 3; i++)
    	{
    		double sum = 0.0;
    
    		for (int j = 0; j < 2; j++)
    		{
    			sum += M[i][j];
    		}
    
    		sums[i] = sum;
    	}
    	for (int i = 0; i < 3; i++)
    	{
    		cout << endl << "In line " << i << " is the sum: " << sums[i];
    	}
    	double sums2[2] = { 0.0, 0.0 };
    	for (int j = 0; j < 2; j++)
    	{
    		double sum2 = 0.0;
    
    		for (int i = 0; i < 3; i++)
    		{
    			sum2 += M[i][j];
    		}
    
    		sums2[j] = sum2;
    	}
    	for (int j = 0; j < 2; j++)
    	{
    		cout << endl << "In Column " << j << " is the sum: " << sums2[j];
    	}
    	cin.get();
    	getchar();
    	return 0;
    }
    


  • Geht das nicht in weniger Zeit? Jedes Element muss doch nur einmal durchlaufen werden. Just sayin'



  • Wahrscheinlich gehts in weniger Zeit wie gesagt ich bin erst seit 3 Wochen da mit dabei beim C++ Kurs von Jan Schaffranek auf Udemy 20 Jahre nach Ende meines Studiums. Für mich ist es ein Hobby aber ich bin immer noch bei den Grundlagen, komme jetzt erst ins Kapitel Vector, Pointer und Referenzen.

    Wäre aber gespannt wenn du mir zeigen könntest wie es effektiver geht, als Anfänger gibt man sich glaube ich schon mal damit zufrieden wenn es so läuft wie es laufen soll



  • @montanistikus1

    #include <cstddef>
    #include <vector>
    #include <iostream>
    
    void sum_up(double *matrix, std::size_t rows, std::size_t columns)
    {
    	std::vector<double> column_sums(columns);
    	for (std::size_t y = 0; y < rows; ++y) {
    		double row_sum{};
    		for (std::size_t x = 0; x < columns; ++x) {
    			row_sum += matrix[y * columns + x];
    			column_sums[x] += matrix[y * columns + x];
    			std::cout << matrix[y * columns + x] << ' ';
    		}
    		std::cout << "= " << row_sum << '\n';
    	}
    	for (std::size_t i = 0; i < columns; ++i)
    		std::cout << column_sums[i] << ' ';
    	std::cout.put('\n');
    }
    
    
    int main()
    {
    	double M[3][2] =
    	{
    		{0.1, 0.2},
    		{0.3, 0.4},
    		{0.5, 0.6}
    	};
    
    	sum_up((double*)M, 3, 2);
    }
    

    Zum Beispiel. Aber es gibt mehrere Möglichkeiten ein multidimensionales Array an eine "Routine" (Funktion??) zu übergeben.



  • Vielen Dank ja die Lösung ist sehr elegant wie gesagt beim Vector bin ich nicht werd versuchen das Ganze trotzdem nachzuvollziehen. Vielen Dank sword dass du dir die Mühe gemacht hast.



  • @Swordfish sagte in Anfängerfrage zu mehrdimensionalen Arrays:

    > std::vector<double> column_sums(rows);
    

    Ich denke, dass sollte besser:

    std::vector<double> column_sums(columns);
    

    heißen.



  • @Belli Danke Belli! 👍



  • @Th69 sagte in Anfängerfrage zu mehrdimensionalen Arrays:

    Du greifst aber mittels M[j][i] zu - und nicht mittels M[i][j]!

    Woher kommt eigentlich die Unsitte solchen Indizes single-letter Namen zu geben? Und dann noch welche die sich zum Verwechseln ähnlich sehen? Ich komm' doch schon bei row und col durcheinander. Sollte eigentlich verboten werden.



  • Tatsächlich. Gute Frage.

    Wahrscheinlich aus BASIC-Zeiten? Wo der Interpreter nur einstellige Variablennamen verstand? Aber soweit ich mich erinnere, waren i, j, k, l, m, n etc. schon immer Zähl-Variablen?



  • @zeropage Ja, schön ... historisch bedingt. Aber wo ist heutzutage der Wert darin sowas zu verbreiten? Vor allem in einem Beispiel wo row und column einfach auch soviel naheliegender ist.



  • Ich schätze, das kommt dann mit der Zeit. Anfangs lernt man halt die Historie, später, wenn man es verstanden hat, gibt man aussagekräftigere Namen.



  • @zeropage Sogar am C64 in BASIC war man schon nicht mehr auf single-letter variable names begrenzt ...

    Ach, werdet doch glücklich mit ausgerechnet i und j.



  • @Swordfish sagte in Anfängerfrage zu mehrdimensionalen Arrays:

    Sogar am C64 in BASIC war man schon nicht mehr auf single-letter variable names begrenzt ...

    Stimmt, jop. Ich überspitze gerne in meinen Kommentaren 😉



  • Also ich finde i als Index OK. Sobald eine zweite Schleife dazukommt j ... nur mehr bedingt. In einem Fall wie diesem würde ich tatsächlich auch row und col verwenden - oder evtl. auch nur r und c. Typischerweise verwendet man ja i für die äussere Schleife und j für die innere - egal über was die beiden Schleifen iterieren. D.h. um zu sehen ob die äussere Schleife über die Zeilen oder Spalten geht, müsste man erst im Schleifenrumpf nachsehen. Das ist unnötige Hirnverdreherei.

    Wenn dagegen anhand der Struktur der Daten klar ist was die innere und was die äussere Schleife ist, können i und j schon "OK" sein. Man darf aber auch gerne besser verständliche Namen verwenden.

    IMO auch relevant: anstatt sich zu überlegen wie man die Indices bei verschachtelten Schleifen nennt, könnte man sich auch überlegen ob es nicht sinnvoll wäre die verschachtelten Schleifen los zu werden. Indem man die innere Schleife in eine eigene Funktion packt. Macht nicht immer Sinn, aber oft genug schon. Dann stellt sich die Frage nicht mehr, und kaum jemand wird beim Lesen ein Problem damit bekommen wenn der Index in beiden Funktionen i heisst.


Anmelden zum Antworten