Zwei Arrays addieren/multiplizieren?



  • Hi Leute!

    Ich soll hier nun eine Methode schreiben, die mir zwei Arrays addiert/multipliziert. Ich hab eine main, die so aussieht:

    int main()
    {
    	srand(unsigned int (time(NULL)));
    
    	matrix test1(3,3);
    	matrix test2(3,3);
    
    	test1.Init();
    	test1.Input();
    	test1.Print();
    
    	test1.Add(test2);
    
    system("Pause");
    return 0;
    }
    

    Wie ihr sehen könnt rufe ich von der Matrix test1 die Add-Methode auf der ich wiederum die Matrix test2 übergebe. Diese Matrizen sollen dann in der Add bzw. Mult-Methode miteinander verrechnet werden. Ich hab nun in der Add/Mult-Methode das Problem, dass ich nicht weiß, wie ich an die Werte der Matrizen rankommen soll... Denn, wenn ich nun den unten gezeigten Code ausführe, dann kann ich mit den indizes nicht die Werte abgreifen, sondern bekomme immer nur den Wert an der ersten Stelle der beiden Arrays...

    void matrix::Add(matrix M)
    {
    	this->feld[1];   //Feld der aufrufenden Matrix
    	M.feld[1];       //Feld der übergebenen Matrix
    }
    


  • Schleife?



  • Oh, ich glaube ich habe mich etwas undeutlich ausgedrückt. Ich bekomme natürlich auch mit einer Schleife keine Werte ausgegeben. Das Problem ist bspw. auch wenn ich den Wert im Array an Stelle 5 adressiere, bekomm ich den Wert an der Stelle 0. Verstehst du?

    Genau das verstehe ich aber nicht...

    void matrix::Add(matrix M)
    {
    	for(int i=0; i<(m*n); i++)
    	{
    		this->feld[i];
    		M.feld[i];
    	}
    }
    

    Ich hab hiermit nun mal deine Idee umgesetzt. Aber auch, wenn ich mich bspw. in Schleifeniteration befinde, wird mir bei beiden Feldzugriffen der Wert von den Arrays an Stelle 0 angezeigt.

    Edit: Oh, entschuldigt bitte. Ich habe den Debugger falsch interpretiert. Wenn ich die Feldzugriffe einer Variabel zuweise, dann werden auch die Werte des jeweiligen Arrays richtig ausgelesen!

    Danke! Ich denke dieser Thread hat sich hiermit wohl vorerst erledigt!


  • Mod

    Beschreib mal, was Zeile 5 und Zeile 6 machen sollen. In Worten, nicht in Code.



  • Zeile 5 und Zeile 6 greifen in Abhängigkeit der Laufvariable i auf den Inhalte der beiden Arrays zu. Ich denke so würde ich es beschreiben.



  • vip@r schrieb:

    Zeile 5 und Zeile 6 greifen in Abhängigkeit der Laufvariable i auf den Inhalte der beiden Arrays zu. Ich denke so würde ich es beschreiben.

    Nächste Frage: Was bringt dir das? 😉



  • Da müsste eigentlich auch eine Warnung kommen...



  • @Nathan: Die Warnung kommt auch. Wie gesagt, ich habe den Debugger falsch interpretiert!



  • void matrix::Mult(matrix M)
    {
    	int hilfsVar = 0;
    
    	if(this->n == M.m)
    	{
    		matrix hilfsFeld(this->m, M.n);
    		hilfsFeld.Init();
    
    		for(int i=0; i<(this->m); i++)
    		{
    			for(int j=0; i<(this->n); i++)
    			{
    				hilfsVar = hilfsVar + this->feld[j] * M.feld[M.n+1];
    			}
    		}
    
    	}
    	else
    	{
    		cout << "Spaltenanzahl der linken Matrix ist ungleich der Zeilenanzahl der rechten Matrix!";
    	}
    }
    

    Ich hab jetzt noch ein kleines weiteres Problem: Ich soll hier ja eine Matrximultiplikation coden. Ich hab hier schon mal ein bisschen rumprobiert, aber irgendwie komm ich jetzt nicht mehr weiter auf grünen Zweig. Das If soll vorher abfragen ob die zwei Felder überhaupt von der Größe her miteinander multipliziert werden können. Wenn nicht, dann gibt sie die Meldung aus. Wenn schon springt er mir in den Algorithmus rein. Die Aufgabe scheint mir so als ob ich einen "naiven" Multiplikationsalgo. coden soll! Also nix mit Strasse und co.

    Vielleicht kann mir ja jemand weiterhelfen? Das wäre nett! Danke!


  • Mod

    Sorgfalt beim Coden!

    for(int j=0; i<(this->n); i++)
    

    Kommt dir das nicht irgendwie komisch vor?

    Da sind noch mehr Fehler drin. Vieles ausgelöst durch schlechten Stil. Nenn hilfsVar mal ergebnis_matrix, i nennst du ergebnis_zeile, j nennst du ergebnis_spalte, M.m nennst du anzahl_zeilen_rechte_matrix, M.n nennst du anzahl_spalten_rechte_matrix, M nennst du rechte_matrix, *this nennst du linke_matrix, usw.
    Dann gehst du noch einmal gründlich durch und guckst, ob das alles so Sinn macht. Dann machst du die vielen Fehler weg, die du dabei findest.

    Ich könnte jetzt noch etwas über Methoden mit Namen wie init, input und print schreiben, sowie die Idee mit der Fehlermeldung, aber bei dir sind erst einmal noch ganz andere Grundlagen viel wichtiger. Programmieren ist nicht Copy&Paste! Programmieren ist seine Gedanken zu ordnen und sauber so zu formulieren, dass jemand anderes (hier ein Computer) ganz genau versteht, was man meint. Nicht irgendwie Wischiwaschi wird schon klappen.



  • Ich hab jetzt mal dein Idee soweit umgesetzt, wie es mir möglich war:

    void matrix::Mult(matrix M)
    {
    	int ergebnis_matrix = 0;
    	int anzahl_zeilen_linke_matrix = this->m, anzahl_spalten_linke_matrix = this->n;
    	int anzahl_zeilen_rechte_matrix = M.m, anzahl_spalten_rechte_matrix = M.n;
    
    	if(anzahl_spalten_linke_matrix == anzahl_zeilen_rechte_matrix)
    	{
    		//Deklaration der Hilfsmatrix
    		matrix hilfs_matrix(anzahl_zeilen_linke_matrix, anzahl_spalten_rechte_matrix);
    		hilfs_matrix.Init();
    
    		for(int ergebnis_zeile=0; ergebnis_zeile<(anzahl_zeilen_linke_matrix); ergebnis_zeile++)
    		{
    			for(int ergebnis_spalte=0; ergebnis_spalte<(anzahl_spalten_rechte_matrix); ergebnis_spalte++)
    			{
    				ergebnis_matrix = ergebnis_matrix + this->feld[ergebnis_spalte] * M.feld[anzahl_spalten_rechte_matrix+1];
    			}
    		}
    
    	}
    	else
    	{
    		cout << "Spaltenanzahl der linken Matrix ist ungleich der Zeilenanzahl der rechten Matrix!";
    	}
    }
    

    Du siehst wahrscheinlich selbst, dass ich am Ablauf an sich noch nichts weiter gemacht habe, sondern mich erst mal um die Variablennamen gekümmert habe. Was ich an dieser Stelle noch sinnvoll finden würde, wäre, wenn ich jetzt zwei Matrixvariablen deklarieren könnte; und zwar folgendermaßen:

    matrix linke_matrix = this->feld
    

    bzw.

    matrix rechte_matrix = M.feld
    

    Leidert mosert der Compiler da. Ist dann sowas an dieser Stelle wohl nicht möglich?


  • Mod

    Dazu habe ich dir doch eigentlich diesen Tipp gegeben. Sträuben sich dir da nicht selber die Haare, wenn du einer Matrix ein M.feld zuweisen möchtest? Was ist denn M? Eine Matrix!

    Außerdem: Kopier doch nicht. Mach einfach eine Referenz:

    matrix &rechte_matrix = M;
    matrix &linke_matrix = *this;
    

    Und denk auch unbedingt daran, in der ersten Zeile damit zu beginnen, die Logik deines Codes zu überprüfen! Schon dort geht etwas schief!



  • Und denk auch unbedingt daran, in der ersten Zeile damit zu beginnen, die Logik deines Codes zu überprüfen! Schon dort geht etwas schief!

    Was bezeichnest du als erste Zeile? Gefällt dir die Deklaration von ergebnis_matrix nicht? Das if wird's wohl nicht sein. Deswegen könnte es höchstens auch noch die äußere for-Schleife sein...

    Hier mal nochmal der Code:

    void matrix::Mult(matrix M)
    {
    	int ergebnis_matrix = 0;
    	matrix &linke_matrix = *this, &rechte_matrix = M;
    	int anzahl_zeilen_linke_matrix = this->m, anzahl_spalten_linke_matrix = this->n;
    	int anzahl_zeilen_rechte_matrix = M.m, anzahl_spalten_rechte_matrix = M.n;
    
    	if(anzahl_spalten_linke_matrix == anzahl_zeilen_rechte_matrix)
    	{
    		//Deklaration der Hilfsmatrix
    		matrix hilfs_matrix(anzahl_zeilen_linke_matrix, anzahl_spalten_rechte_matrix);
    		hilfs_matrix.Init();
    
    		for(int ergebnis_spalte=0; ergebnis_spalte<anzahl_spalten_linke_matrix; ergebnis_spalte++)
    		{
    			for(int ergebnis_zeile=ergebnis_spalte; ergebnis_zeile<anzahl_zeilen_linke_matrix; ergebnis_zeile++)
    			{
    
    			}
    		}
    	}
    	else
    	{
    		cout << "Spaltenanzahl der linken Matrix ist ungleich der Zeilenanzahl der rechten Matrix!";
    	}
    }
    

    Ich hab hier nun nu irgendwie das Problem, dass ich mir nicht vorstellen kann, wie ich mit Code ausdrücke, dass ich das erste Element (1,1) der linken Matrix mit dem (1,1) Element der rechten Matrix multipliziere. Als nächsten Schritt dann aber (2,1) und (1,2) miteinander multipliziere. Wenn ich ein zweidimensionales Array hätte und über [][] zugreifen könnte, hätte ich (wahrscheinlich) weniger Problem. Aber hier das mit einem eindimensionalen Arry abzubilden ist sehr schwierig für mich!


  • Mod

    vip@r schrieb:

    Was bezeichnest du als erste Zeile? Gefällt dir die Deklaration von ergebnis_matrix nicht? Das if wird's wohl nicht sein. Deswegen könnte es höchstens auch noch die äußere for-Schleife sein...

    Nein, ich meine die erste Zeile! Wo soll hinterher das Ergebnis hin? Kann das passen? Falls das wirklich so gemeint ist: Machst du später im Code auch das, was du hier meinst? Irgendetwas passt hier nämlich ganz und gar nicht zusammen.

    Ich hab hier nun nu irgendwie das Problem, dass ich mir nicht vorstellen kann, wie ich mit Code ausdrücke, dass ich das erste Element (1,1) der linken Matrix mit dem (1,1) Element der rechten Matrix multipliziere. Als nächsten Schritt dann aber (2,1) und (1,2) miteinander multipliziere. Wenn ich ein zweidimensionales Array hätte und über [][] zugreifen könnte, hätte ich (wahrscheinlich) weniger Problem. Aber hier das mit einem eindimensionalen Arry abzubilden ist sehr schwierig für mich!

    Da gibt es eine einfache Lösung: Schreib eine Funktion dafür! Dann brauchst du bloß ein einziges Mal überlegen, wie du in einer MxN-Matrix wohl das Element an der Stelle (a,b) bekommst und kannst diese Lösung dann immer wieder benutzen.
    Teste die Funktion aber gut an einem einfachen Beispiel, bevor du sie hier einsetzt!



  • Bevor ich mich an eine Funktion mache, würde ich mich freun, wenn du dir den nachfolgenden Code noch kurz ansiehst. Könnte das so funktionieren? Das einzige Problem wo ich hier jetzt nun noch hab, ist, ich weiß nich in welcher Reihenfolge ich die Laufvariablen einsetzen muss, dass ich auf das richtige Ergebnis komme...

    void matrix::Mult(matrix M)
    {
    	matrix &linke_matrix = *this, &rechte_matrix = M;
    	int anzahl_zeilen_linke_matrix = this->m, anzahl_spalten_linke_matrix = this->n;
    	int anzahl_zeilen_rechte_matrix = M.m, anzahl_spalten_rechte_matrix = M.n;
    
    	if(anzahl_spalten_linke_matrix == anzahl_zeilen_rechte_matrix)
    	{
    		//Deklaration der Hilfsmatrix
    		matrix hilfs_matrix(anzahl_zeilen_linke_matrix, anzahl_spalten_rechte_matrix);
    		hilfs_matrix.Init();
    
    		for(int counter_spalten_rechte_matrix=0; counter_spalten_rechte_matrix<anzahl_spalten_rechte_matrix; counter_spalten_rechte_matrix++)
    		{
    			for(int counter_spalten_linke_matrix=0; counter_spalten_linke_matrix<anzahl_spalten_linke_matrix; counter_spalten_linke_matrix++)
    			{
    				for(int counter_zeilen_linke_matrix=0; counter_zeilen_linke_matrix<anzahl_zeilen_linke_matrix; counter_zeilen_linke_matrix++)
    				{  
    					hilfs_matrix.feld[] = hilfs_matrix.feld[] + linke_matrix.feld[] * rechte_matrix[];
    				}
    			}
    		}
    
    		hilfs_matrix.Print();
    	}
    	else
    	{
    		cout << "Spaltenanzahl der linken Matrix ist ungleich der Zeilenanzahl der rechten Matrix!";
    	}
    }
    

    Könntest du mir vielleicht etwas gezielter nachhelfen?


  • Mod

    Ich glaube, du hast wahrscheinlich die falsche Idee. Vielleicht solltest du nicht die rechte und die linke Matrix durchiterieren, sondern die Einträge (zeile und spalte) der Ergebnismatrix. Du weißt ja schon aus Zeile 10, wie weit du jeweils zählen musst. Zu jedem Eintrag weißt du dann ja sicherlich auch die Formel, wie man aus der linken und rechten Matrix den entsprechenden Eintrag berechnen kann. Das ist wieder ein großartiger Anwendungsfall für eine eigene Funktion.

    Versuch dir anzugewöhnen, Probleme in einfachere Probleme zu zerlegen. Das ist eine sehr wirkungsvolle Problemlösungsstrategie mit der man fast alles knacken kann.



  • SeppJ schrieb:

    Versuch dir anzugewöhnen, Probleme in einfachere Probleme zu zerlegen. Das ist eine sehr wirkungsvolle Problemlösungsstrategie mit der man fast alles knacken kann.

    Der Tipp hat mir nie geholfen.

    Zum Beispiel war
    Schule des Denkens | ISBN: 3772006086
    für mich einfach ein Fehlkauf, obwohl andere voll drauf schwören.

    So ein Programmierding löse ich, wenns zu schwierig wäre, es direkt reinzuhacken, indem ich per Hand so lange Matrizen plutimiziere, bis mein Vorgehen sonnenklar und regelmäßig ist und dann wird er reingehackt.



  • Volkard, troll dich und manipuliere nicht andere Leute …



  • <anonym> schrieb:

    Volkard, troll dich und manipuliere nicht andere Leute …

    "Helfen" ist immer "Manipulieren".
    Ich habe ausreichend deutlich gemacht, daß das ein lokales Problem von mir ist. Aber vielleicht trifft es auch vip@r. Oder noch andere Leser. Die haben dann einen Aspekt mehr, als Ergänzung zu SeppJs Hauptlösung.


Log in to reply