Matrix n x n < C/C++ < Programmiersprachen < Praxis < Informatik < Vorhilfe
|
Aufgabe | [Dateianhang nicht öffentlich] |
Ich hab das Programm noch nicht programmiert. Sammle sozusagen noch ein paar Ideen.
Ein Lösungsansatz wäre von mir einen Zeiger zu definieren (**matrix) wobei die Zeilen und Spalten (n x n) in einem Array sind.
Die Zeilen und Spalten werden von Benutzer durch cin << n
eingegeben, anschließend die Werte für [mm] a_{ij} [/mm] .
Mein Hauptproblem ist allerdings, wie kann ich das ganze transponieren? Dh die Zeile zur Spalte (und umgekehrt) machen?
Dateianhänge: Anhang Nr. 1 (Typ: jpg) [nicht öffentlich]
|
|
|
|
Status: |
(Antwort) fertig | Datum: | 19:16 Di 13.11.2007 | Autor: | Gilga |
Array von Zeigern auf arrays ist schon die richtige Idee.
Transponieren is doch nicht schwer. ...
for i=1,...n
for j=i,...n
tmp = A[i,j]
A[i,j]=A[j,i]
A[j,i]=tmp
|
|
|
|
|
Status: |
(Mitteilung) Reaktion unnötig | Datum: | 20:05 Di 13.11.2007 | Autor: | Fibonacci- |
1: | #include <iostream>
| 2: | using namespace std;
| 3: | int main (){
| 4: |
| 5: | double **matrix;
| 6: | double x;
| 7: | double n;
| 8: | cout << "Geben die den Rang (n x n) der Matrix ein: " << "\n";
| 9: | cin >> n;
| 10: | *matrix = (n,n);
| 11: |
| 12: | for (int i=1; i<=n;i++){
| 13: | for (int j=1; j<=n;j++){
| 14: |
| 15: | matrix [j,i]= x;
| 16: | matrix [j,i]= matrix [i,j];
| 17: | matrix [i,j] = x;
| 18: | }}
| 19: | cout << x <<;
| 20: | } |
Ich weiß nicht mehr wie es weiter geht :(
ich finde den Fehler in Zeile 10 nicht^^
|
|
|
|
|
Status: |
(Mitteilung) Reaktion unnötig | Datum: | 20:31 Di 13.11.2007 | Autor: | Martin243 |
Hallo,
du sollst aber eine Integer-Matrix basteln, keine mit Doubles! Alles, was hier vorkommt, sollte schon den Typ int (bzw. Pointer darauf) haben.
Was in Zeile 10 steht, gibt es in C/C++ nicht.
Du musst schon mit malloc() arbeiten. Das ist die Funktion, die man typischerweise als erste kennenlernt, wenn man von dynamischer Allokation spricht.
Du kannst mit einem einfachen Array, einer Allokation und etwas mehr Pointerarithmetik arbeiten oder mit einem Doppelarray, zwei oder mehr Allokationen und ohne (oder mit wenig) Pointerarithmetik arbeiten. such dir etwas aus. Aber um malloc kommst du nicht herum.
Ach ja: Wo malloc ist, darf free nicht fehlen, sonst gibt es Speicherlecks.
Schau mal in deine Unterlagen, was du zu dyn. Speicherallokation findest.
Gruß
Martin
|
|
|
|
|
Der Begriff malloc() ist mir vollkommen neu! Free ebenfalls...
Man kann doch auch die Matrix folgendermaßen zusammenstellen:
1 -> mit zeiger1
2 -> mit Zeiger2
3 -> ...
4 -> ...
5 -> ...
Zeiger1 -> 1, 2, 3, 4, 5
Zeiger2 -> 1, 2, 3, 4, 5
Die Zahlen sind nur ein Bsp für eine 5x5 Matrix...
Ich hab jetzt **matrix [n,n] deklariert
|
|
|
|
|
Ach, wir sind ja bei C++. Dann sagen dir vielleicht new und delete etwas? Das sind die Pendants zu malloc und free.
Du deklarierst zuerst einen Zeiger auf Zeiger:
int** Matrix;
Sobald klar ist, wie groß die Matrix ist, kannst du erstmal die Zeiger in die einzelnen Zeilen anlegen:
Matrix = new int*[n];
Dann musst du in einer Schleife jede Zeile einzeln erzeugen:
for (i=0;i<n;++i) Matrix[i] = new int[n];
Erst danach hast du genug Speicher und kannst die Werte zuweisen.
Am Ende solltest du das delete[] nicht vergessen!
Gruß
Martin
|
|
|
|
|
Super =) das war eigentlich schon die Sache mit new und delete!
das Matrix [i] beinhaltet doch jetzt die Spalte?
die Speicherzuweisung ist ja schon erfolgt.
Wie fülle ich das ganze mit Leben, dh mit Zahlen?
Das mit dem transponieren, werd ich noch hinkriegen... sonst weiß ich auch nicht mehr weiter.
*Sry dass ich so detailliert frage...
Problem ist, dass ich z.Zt. aufgrund meiner Krankheit nacharbeiten muss und der Prof mir nicht mal den Skript aushändigen will :(
|
|
|
|
|
Status: |
(Mitteilung) Reaktion unnötig | Datum: | 20:48 Do 15.11.2007 | Autor: | Fibonacci- |
Mein Ansatz wäre dabei
int x;
cout << "Geben Sie den wert für a11 ein: ";
cin >> x;
Matrix[0]=x;
...
Das geht doch bestimmt auch kürzer oder funktioniert das ebenfalls mit new/delete?
|
|
|
|
|
Hallo,
> das Matrix [i] beinhaltet doch jetzt die Spalte?
Nein. Matrix[i] ist der Zeiger auf ein Array, das die Daten der i-ten (bei 0 angefangen) Zeile enthält.
Ich versuche mal zu verdeutlichen, was die einzelnen Schritte machen:
int** Matrix;
Hier wird ein Zeiger deklariert, der auf einen anderen Zeiger zeigt. Im Moment zeigt der Zeiger irgendwohin. Das soll der gestrichelte Pfeil andeuten, der einfach in die Gegend zeigt.
[Dateianhang nicht öffentlich]
Matrix = new int*[n];
Wir erzeugen ein neues Array von Zeigern, die auf int-Werte zeigen sollen, und weisen die Adresse des Arrays (= des ersten Elements des Arrays) unserem Zeiger Matrix zu. Jedes Element des Arrays soll später auf eine Zeile der Matrix zeigen. Im Moment zeigen sie aber wieder irgendwohin.
In der Zeichnung soll die Matrix n x n groß sein.
[Dateianhang nicht öffentlich]
for (i=0;i<n;++i) Matrix[i] = new int[n];
Nun legen wir in einer Schleife jede Zeile einzeln an. Hierzu erzeugen wir für jede Zeile ein int-Array, das später die Werte dieser Zeile enthalten soll, und weisen jeweils die Adresse des i-ten Arrays dem Zeiger Matrix[i] zu. Wir müssen die Schleife also n-mal durchlaufen, weil wir wirklich jede Zeile einzeln anlegen.
Innerhalb jeder Zeile können wir nun das j-te Element auswählen. Insgesamt erhalten wir durch Matrix[i][j] das Element in der i-ten Zeile und j-ten Spalte.
Allerdings ist unsere Matrix noch nicht initialisiert! Wir können sie zwar auslesen, bekommen aber die Werte, die zufällig an dieser Stelle im Speicher standen.
[Dateianhang nicht öffentlich]
Nun kommen wir zur Initialisierung:
Nun nimmst du zwei verschachtelte Schleifen, in denen i und j die Werte 0 bis n-1 durchlaufen, wobei die Frage, ob i oder j in der äußeren Schleife stehen soll, sich danach richtet, ob du die Matrix zeilen- oder spaltenweise initialisieren willst.
Dabei brauchst du keine temporäre Variable wie x. Du kannst den Wert von cin direkt der ensprechenden Stelle in der Matrix zuweisen:
cout << " a(" << (i+1) << "," << (j+1) << " = ";
cin >> Matrix[i][j];
Jetzt noch die beiden Schleifen drumherum und es läuft.
Das Transponieren ist wirklich nicht schwer und wurde oben sogar vorgemacht.
Gruß
Martin
Dateianhänge: Anhang Nr. 1 (Typ: gif) [nicht öffentlich] Anhang Nr. 2 (Typ: gif) [nicht öffentlich] Anhang Nr. 3 (Typ: gif) [nicht öffentlich]
|
|
|
|
|
Status: |
(Mitteilung) Reaktion unnötig | Datum: | 22:06 Do 15.11.2007 | Autor: | Fibonacci- |
Zeiger sind kompliziert :)
aber ich hab das jetzt verstanden!
Danke für deine große Mühe!
Werde dann nachher (eventuell morgen) den Code hier zur Verfügung stellen.
Nochmals vielen Dank =)
|
|
|
|
|
1: | # include <iostream>
| 2: | using namespace std;
| 3: | int main()
| 4: | {
| 5: | int i,j,n,trans;
| 6: | int** Matrix;
| 7: | cout << "Geben Sie eine natuerliche Zahl n ein: " ;
| 8: | cin >> n;
| 9: | Matrix = new int*[n];
| 10: | for (i=0;i<n;++i)
| 11: | Matrix[i] = new int[n];
| 12: |
| 13: | for (i=0; i<=n-1; i++){
| 14: | for (j=0; j<=n-1; j++)
| 15: |
| 16: | cout << " a(" << (i+1) << "," << (j+1) << ") = ";
| 17: | cin >> Matrix[i][j];
| 18: | }
| 19: | for (i=0; i<=n-1; i++){
| 20: | for (j=n-1; j>=0; j--)
| 21: |
| 22: | trans = Matrix[i][j];
| 23: | Matrix[i][j]=Matrix[j][i];
| 24: | Matrix[j][i]=trans; //???
| 25: | cout << Matrix[i][j] << "\n";
| 26: | }
| 27: | } |
Warum erfolgt nun keine Ausgabe bei Matrix [i][j] ?
|
|
|
|
|
Hallo,
vergiss bei deinen for-Schleifen die geschweiften Klammern nicht!
Gruß
Martin
|
|
|
|
|
Status: |
(Mitteilung) Reaktion unnötig | Datum: | 13:04 So 18.11.2007 | Autor: | Fibonacci- |
Vielen Dank @ Martin !
Hier nochmal der Code für die Interessenten:
1: | # include <iostream>
| 2: | using namespace std;
| 3: | int main()
| 4: | {
| 5: | int** Matrix;
| 6: | int trans;
| 7: | unsigned int n;
| 8: |
| 9: | cout << "Geben Sie eine natuerliche Zahl n ein: " ;
| 10: | cin >> n;
| 11: | Matrix = new int*[n];
| 12: | for (int i=0;i<n;++i)
| 13: | Matrix[i] = new int[n];
| 14: |
| 15: | for (int i=0; i<=n-1; i++){
| 16: | for (int j=0; j<=n-1; j++){
| 17: |
| 18: | cout << " a(" << (i+1) << "," << (j+1) << ") = ";
| 19: | cin >> Matrix[i][j];
| 20: | }
| 21: | }
| 22: | for (int i=0; i<=n-1; i++){
| 23: | for (int j=0; j<=n-1; j++){
| 24: |
| 25: | trans = Matrix[i][j];
| 26: | Matrix[i][j]=Matrix[j][i];
| 27: | Matrix[j][i]=trans; //???
| 28: | cout << "At_(" << i << "," << j << ") =" << Matrix[i][j] << "\n";
| 29: | }
| 30: | }
| 31: | } |
|
|
|
|
|
Status: |
(Mitteilung) Reaktion unnötig | Datum: | 13:50 So 18.11.2007 | Autor: | Martin243 |
Hallo,
prima, aber du hast vergessen, den allozierten Speicher am Ende wieder freizugeben. Du solltest noch ein
delete[] Matrix;
einbauen, sonst nimmst du Speicher und gibst ihn nie wieder frei!
Nur so am Rande:
Weißt du, dass man die Werte zweier Variablen vertauschen kann, ohne eine temporäre Variable (temp in deinem Fall) zu Hilfe nehmen zu müssen? Eine Möglichkeit wäre:
Matrix[i][j] += Matrix[j][i];
Matrix[j][i] = Matrix[i][j] - Matrix[j][i];
Matrix[i][j] -= Matrix[j][i];
Na, alles klar?
Gruß
Martin
|
|
|
|
|
Status: |
(Mitteilung) Reaktion unnötig | Datum: | 22:18 So 18.11.2007 | Autor: | Fibonacci- |
> Hallo,
>
> prima, aber du hast vergessen, den allozierten Speicher am Ende wieder
> freizugeben. Du solltest noch ein
> delete[] Matrix;
> einbauen, sonst nimmst du Speicher und gibst ihn nie wieder frei!
Stimmt... sowas vergisst man gerne mal :)
> Nur so am Rande:
> Weißt du, dass man die Werte zweier Variablen vertauschen kann, ohne eine
> temporäre Variable (temp in deinem Fall) zu Hilfe nehmen zu müssen? Eine
> Möglichkeit wäre:
> Matrix[i][j] += Matrix[j][i];
> Matrix[j][i] = Matrix[i][j] - Matrix[j][i];
> Matrix[i][j] -= Matrix[j][i];
> Na, alles klar?
Klar -.- logisch... man lernt! :) Vielen Dank!
|
|
|
|
|
Hallo, auch auf diesem Weg eine Matrix erstellt. Es funktioniert auch alles gut solange ich eine betsimmte matrixgröße nicht überschreite (300x300). Da ich aber eine Matrx der Größe(600x600) anlegen möchte, bekomme ich folgende Fehlermeldung: Unhandled exception at 0x00427aad in ZeigerTest.exe: 0xC0000005: Access violation reading location 0x01428000
Hat jemand ne Idee, wie ich den Fehler beheben könnte?
|
|
|
|
|
> Hallo, auch auf diesem Weg eine Matrix erstellt. Es
> funktioniert auch alles gut solange ich eine betsimmte
> matrixgröße nicht überschreite (300x300). Da ich aber eine
> Matrx der Größe(600x600) anlegen möchte, bekomme ich
> folgende Fehlermeldung: Unhandled exception at 0x00427aad
> in ZeigerTest.exe: 0xC0000005: Access violation reading
> location 0x01428000
>
> Hat jemand ne Idee, wie ich den Fehler beheben könnte?
Wenn die Matrix grösser wäre, würde ich sagen: Ab einer gewissen Grösse der Matrix kommt es beim Allozieren zu einer "out of memory" Bedingung, die aber scheinbar nicht zu einer Exception mit entsprechender Meldung führt (warum ist weniger klar).
Wenn Du dann auf die nur teilweise allozierte Matrix zuzugreifen versuchst, dereferenzierst Du eine ungültige Adresse, was zur "access violation" führt.
Merkwürdig ist allerdings, dass diese access violation beim Lesen geschieht.
Wir haben also zwei Indizien, die gegen eine out of memory Bedingung sprechen: dass keine out of memory Exception signalisiert wird und dass die access violation beim Lesen geschieht.
Deshalb vermute ich, dass Dein Programm nicht Ordnung sein dürfte. Denn wenn Dein Programm korrekt wäre, dann müsste die erste access violation beim *Schreiben* (nicht aber aber beim *Lesen*) auftreten. In einem *korrekten* Programm darfst Du nämlich auf nicht-initialisierten Speicher gar nicht zugreifen. (Ausser Du gehst davon aus, dass die Elemente eines neu allozierten Arrays passend initialisiert sind.) Hmm. Vielleicht solltest Du Dein ganzes Programm hier im Forum offenlegen.
|
|
|
|