zweidim. Array - Matrix auf ob. Dreiecksmatrix prüfen

Jo.Mo.

Aktives Mitglied
Problem steht eigentlich schon im Topic. Ich soll eine quadratische Matrix, ergo ein 2-dimensionales Array prüfen, ob es im linken unteren Bereich Nullen enthält. Was dann ja einer oberen Dreiecksmatrix entsprechen sollte... :) Das ganze soll als Methode implementiert werden.

Ich hatte verschd. Möglichkeiten mittels for-Schleife versucht, das hat aber nix getaugt. Da ich ja im Endeffekt nur auf boolean prüfe, vermute ich, ich stell mich zu doof an oder es hat jemand eine idee, wie man das kurz und schmerzlos lösen kann.

mein letzter Ansatz sah etwa so aus:
Java:
public class MatrixOperation {

    public static boolean pruefe (int[][] matrix)

    	for (int i = n-1; i > -1 n; i--) {

            sum = 0;

            for (j = i + 1; j < n; j++) {

                sum += u[i][j]*x[j];

            }

            x[i] = (y[i] - sum)/u[i][i];
          
          return true;  
    	}



    public MatrixOperation() {
    }


}
 
Zuletzt bearbeitet:

Jo.Mo.

Aktives Mitglied
...sorry, da ist wohl was schiefgegangen, wird gleich geändert... :)

...ich weiss nicht, ob es mit einer anderen Bedingungsart nicht vielleicht eleganter wäre. Mir gehts aber in erster Linie darum, was funktionsfähiges gebacken zu bekommen. Mit den throw-Sachen komme ich noch nicht ganz klar, aber irgendeine Möglichkeit, Fehler abzufangen (und in dem Falle false zurückzugeben) will ich schon noch einbauen...
 
Zuletzt bearbeitet:

Jo.Mo.

Aktives Mitglied
EDIT: Achso, Nebenfrage: Was muss denn zwingend in der Main-Methode stehen, damit ich die korrekte Funktionsweise der Methode prüfen kann...?
 

XHelp

Top Contributor
Die äußere Schleife macht kein Sinn, weil du direkt im 1. Schritt etwas zurückgibst. Summe brauchst du auch nicht. Du musst ja nur Prüfen, ob sich eine Zahl die !=0 ist sich in bestimmten Bereichen befindet:
Code:
1 2 3 4 //0. Zeile
0 5 6 7 //du bist in der 1. Zeile und 1 Zahl von links soll 0 sein
0 0 9 1 //du bist in der 2. Zeile und 2 Zahlen von links sollen 0 sein
0 0 0 2 //du bist in der 3. Zeile und 3 Zahlen von links sollen 0 sein
// du bist in der n. Zeile und n Zahlen von links sollen 0 sein
Das Muster müsste erkennbar sein.

Außerdem greifst du in deiner Methode auf irgendwelche völlig anderen Matritzen zu.
 
Zuletzt bearbeitet:

Final_Striker

Top Contributor
ich würde so was machen wie

Java:
public static boolean pruefe (int[][] matrix)
{
   for (int i =...) {

      for (int j = ...) {

         if(matrix[i][j] != 0)
            return false;
      }
   }
   return true;  
}

jetzt musst du nur noch die Schleifen über das Drittel der Matrix laufen lassen. ;-)
 

Jo.Mo.

Aktives Mitglied
...tja, wenn ich jetzt wüsste wie ich das auf die Dreiecksform begrenze, wär ich glücklich. Ausgehend davon, das i die zeilen sind und j die Spalten, fange ich doch erst in der zweiten Zeile an, und addiere dann als vorgabe für die Anzahl der Nullen pro Zeile um eins auf. Ich weiss nicht ob es so hinhaut, also immer her mit der kritik. :)

Java:
public class MatrixOperation {

    	public static boolean pruefe (int[][] matrix) {
    		
            for (int i = 1; i < n; i++) {
 
                for (int j = 2; j < n; j++) {
 
                    if(matrix[i][j] != 0)
                      return false;
                }
            }
            return true;  
        }



    public MatrixOperation() {
    }


}
 

XHelp

Top Contributor
Das j sollte bei 0 anfangen.
Code:
j<n
stimmt auch nicht. Du musst ja es irgendwie abhängig von der Zeilennummer (und nicht -anzahl) machen. Also würde es sich anbieten sowas wie
Code:
j<i
zu machen.
 

Jo.Mo.

Aktives Mitglied
...vielleicht habe ich einen denkfehler, aber wie komme ich dadurch auf die Dreiecksform...? Ich glaub ich muss mir über die Feiertage nochmal einiges an Lektüre vornehmen... :(
 

Jo.Mo.

Aktives Mitglied
genau das habe ich ja schon im letzten Post geschrieben. Vielleicht liegts daran das ich mit dem j und i nicht klarkomme. i sind die Zeilen, j die Spalten, oder? Und aus der Bedingung Zeilen grösser Spalten ist für mich noch kein Dreieck ersichtlich. Vielleicht seh ich den Wald vor lauter Bäumen nicht, und ich habe da auch keine Sicht wie ein Java-Pro, ich schau es mir morgen vormittag nochmal an.
 

Final_Striker

Top Contributor
1 2 3 4
0 5 6 7
0 0 9 1
0 0 0 2

Die erste for-Schleife läuft über die Zeilen und dir zweite for-Schleife über die Spalten. Du musst zwar über alle Zeilen laufen (ok, über die erste ist es unnötig, aber was solls) aber nicht über alle Spalten. Das bedeutet, du musst die Bedingung wie lange die zweite Schleifen laufen muss anpassen.

Wenn du dir die Matrix anschaust und überprüfst wie lange die zweite Schleife immer in einer Zeile laufen muss, sollte dir eine Abhängigkeit zwischen den Zeilennummer und der Anzahl der Nullen auffallen.
 

Jo.Mo.

Aktives Mitglied
...und überprüfst wie lange die zweite Schleife immer in einer Zeile laufen muss, sollte dir eine Abhängigkeit zwischen den Zeilennummer und der Anzahl der Nullen auffallen

...du meinst, wie lange die Zweite Zeile in einer Spalte laufen muss, oder? Die erste Bedingung kann dann ja so bleiben, nur die zweite, also j, die Spalten, sollte, wenn ich dich richtig verstanden habe, in diese Richtung gehen...

Java:
public class MatrixOperation {

    	public static boolean pruefe (int[][] matrix) {

            for (int i = 0; i < n; i++) {

                for (int j = i+1; j < i; j++) {

                    if(matrix[i][j] != 0)
                      return false;
                }
            }
            return true;
        }



    public MatrixOperation() {
    }


}

...wenn ich den Bedingungsablauf richtig interpretiere, sollte er doch jetzt, solange die Spaltenanzahl noch nicht die Zeilenanzahl ist, prüfen ob in dr 2. Zeile eine Null, in der 3. 2 Nullen usw. stehen. Oder anders ausgedrückt müssen in der 1. Spalte 3 Nullen, in der 2.Spalte 2 Nullen und in der 3. Spalte 1 Null stehen. Über den letzten Teil bin ich mir schon im klaren, nur über den for-Ablauf rätsel ich.

Die 3 Anweisungen in der for-schleife sagen ja: Setze den Zähler auf ...; prüfe ob der Zahler kleiner/gleich ... ist; inkrementiere um 1.
 

XHelp

Top Contributor
Naja, um genau zu sein läuft die Schleife jetzt überhaupt nicht. Weil der Wert am Anfang
Code:
i+1
ist und die Schleifenbedingung
Code:
j<i
ist
 

Final_Striker

Top Contributor
Ach stimmt, sorry. Hab das [c]j < i[/c] übersehen.

Edit:

@Jo.Mo.

Mal ein Tipp, wenn du mal nicht weiterkommst, einfach ein Blatt Papier nehmen und die Sachen aufzeichnen.

Lass am besten auch die erste Zeile der Matrix weg, also i von 1 und nicht von 0 laufen lassen -> [c]int i = 1[/c]

Matrix n = 4

1 2 3 4
0 5 6 7
0 0 9 1
0 0 0 2

Code:
Zeile (i).   j muss von - bis laufen

1.   0 - 0
2.   0 - 1
3.   0 - 2
Vergleiche jetzt die Zeilennummer mit der Position bis zu der j laufen muss.
 
Zuletzt bearbeitet:

Jo.Mo.

Aktives Mitglied
...also i-1? Was ich im letzten Post geschrieben hab, stimmt doch, oder? Könnt ihr mir zumindest einen Tip geben oder aufklären, ob ich das mit der Schleife richtig verstehe? Wenn ich weder sicher sein kann, ob ich den Bedingungsablauf richtig interpretiere noch einen Ansatz dahingehend habe, kann ich nur raten - wenig zielführend...
 

Jo.Mo.

Aktives Mitglied
@Final Striker: Danke, werd ich gleich nochmal machen. Hatte das zwar anfangs so probiert, aber irgendwie bin ich mir unklar darüber, was durch die anweisungen genau passiert.

1. Die 3 Anweisungen in der for-schleife sagen ja: Setze den Zähler auf ...; prüfe ob der Zahler kleiner/gleich ... ist; inkrementiere um 1.

- stimmt doch, oder?

2.mit der 1. for-bedingung (i) durchlaufe ich die Zeilen, die 2. innere for schleife läuft spaltenweise durch (j), richtig?

EDIT: Irgendwie habe ich keinen Plan, was i und j eigentlich darstellen sollen - bzw. es sind Faktoren, die in der Bedingung festgelegt, geprüft und inkrementiert werden, aber mir fehlt da die Vorstellung wie ich durch die beiden verschachtelten bedingungen auf die Spalten und Zeilen einfluss nehme. Klingt doof, aber ich bin nicht sicher ob ich verstehe was durch die Bedingungen genau vorgeht, bzw. an welcher Stelle. ;(
 
Zuletzt bearbeitet:

Jo.Mo.

Aktives Mitglied
...ich arbeite mich jetzt mal vor. (ausgehend von dem Tip von Final Striker)

Angenommen die Matrix ist n =4

1 2 3 4
0 5 6 7
0 0 9 1
0 0 0 2

for (i = 0; i < n; i++):
die erste Bedingung setzt den Zähler auf null, prüft, ob i (anfangs 0) kleiner als n (Dimension der Matrix) ist und inkrementiert dann um 1. - das läuft solange, wie i nicht 4 ist. Sind i nun die Spalten oder die Zeilen? Wenn Spalten, ist es richtig (weil in der letzten ja keine Nullen sind) wenn Zeilen geht er nur bis zur 3 Zeile (falsch, denn in der 4 zeile stehen ja 2 Nullen).

Solange die erste bedingung nicht erfüllt ist, springt er nach dem Inkremetieren auf die nächste Bedingung:

for (j = 0; j < i; j++): Setzt j auf 0, prüft, ob j kleiner i ist (was im ersten Anlauf dann 1 wäre), und inkrementiert ebenfalls um 1.

in der if Bedingung wird nun geprüft, ob die Matrix an der Stelle (hier im ersten Anlauf [1][0] den wert 0 hat - wenn nicht, wird false zurückgegeben und die 1. Bdeingung startet neu.

Habe ich das jetzt richtig nachvollzogen oder wo liegt mein Fehler...?
 

andiv

Bekanntes Mitglied
Das ist deine Matrix, i ist der Zeilenindex, j ist der Spaltenindex:
Code:
 j=0 1 2 3 
i=
0  ? ? ? ?
1  0 ? ? ?
2  0 0 ? ?
3  0 0 0 ?

Überprüft werden müssen folgende Elemente:
matrix[1][0],
matrix[2][0], matrix[2][1]
matrix[3][0], matrix[3][1], matrix[3][2]

Wenn der Programmcode so aussieht
Java:
for (int i = 0; i < n; i++) {

    for (int j = 0; j < i; j++) {

        if(matrix[i][j] != 0)
            return false;
        }
}
return true;

dann laufen die Schleifen folgendermaßen
i=0: innere schleife wird nicht durchlaufen
i=1: j=0 da 0<1
i=2: j=0 da 0<2, j=1 da 1<2
i=3: j=0 da 0<3, j=1 da 1<3, j=2 da 2<3

Du solltest erkennen dass so genau die richtigen Elemente überprüft werden.
 

Final_Striker

Top Contributor
[c]for(int j = 0; j < i; j++)[/c]

Laufe von 0, solange j kleiner i ist in einer Schritten [c]j++ <- identisch mit -> j = j + 1[/c].


Und wie du oben schon geschrieben hast muss das [c]j[/c] immer bis [c]i-1[/c] laufen.
 

Jo.Mo.

Aktives Mitglied
...ah, jetzt wird mir einiges klar. Ich hatte schon nicht berücksichtigt das das array schon bei [0][0] anfängt, dachte an [1][1]. Dumm von mir.

Ich habe es zwar etwas schlecht und unübersichtlich formuliert, aber darauf wollte ich in etwa hinaus. Mein 2. Fehler war, das ich nicht berücksichtigt habe das die innere Schleife ab i=2 solange durchläuft bis j=i-1 ist. Also das erst [2][0] und anschliessend [2][1] geprüft wird, das hat mich da aus dem Konzept gebracht.


...was muss denn mindestens in der main-Methode stehen, damit ich den Ablauf testen kann?

Java:
public class MatrixOperation {

    	public static boolean pruefe (int[][] matrix) {

            for (int i = 0; i < n; i++) {

                for (int j = 0; j < i; j++) {

                    if(matrix[i][j] != 0)
                      return false;
                }
            }
            return true;
        }



    public MatrixOperation() {
    }


}

EDIT: @Final Striker: Ja, das inkrementieren war mir schon klar, nur um das j hatte ich einen Denkfehler, s.o.
 

Final_Striker

Top Contributor
Die Matrix die du der Methode mitgeben musst.^^

außerdem

[c]for (int i = 0; i < n; i++) {[/c]

musst du anstatt n die Länge der Matrix einsetzen.
 

Jo.Mo.

Aktives Mitglied
Java:
public class MatrixOperation {

    	public static boolean pruefe (int[][] matrix) {
    		
    		if (){
    		   return null;

    		} else { for (int i = 0; i < n; i++) {

                   for (int j = 0; j < i; j++) {

                       if(matrix[i][j] != 0)
                         return false;
                   }
              } return true;
              }
    	}

        public static int[] matVek(int[][]m, int[]v) {

            int array2[][] = new int[3][3];
            for(int i = 0; i < x; i++) {
			    for(int j = 0; j < y-1; j++) {
				    for(int k = 0; k < y; k++){

					array2[i][j] += array[i][k]*array1[k][j];
				    }
			    }
            }
        }



    public static void main(String[] args) {


        int[][] array = new int[][];
    	int array[][] = {{5,6,7},{4,8,9}};
		int array1[][] = {{6,4},{5,7},{1,1}};

		System.out.print(" "+array2[i][j]);


    }


}


...irgendwelche Verbesserungsvorschläge? Ich habe zusätzlich noch eine Multiplikationsoperation Matrix*Vektor eingebaut, noch nicht ganz fertig, und die pruefe Methode will ich grob absichern, dass er Referenz null zurückgibt, falls Multiplikation nicht möglich ist.

Die Arrays in der Main methode änder ich gerade, dass man diese selbst eingibt. Ergebnis poste ich gleich.
 

XHelp

Top Contributor
Die If-Abfrage ist ziemlich sinnfrei. Außerdem kam ja schon der Tipp, dann du
Code:
n
wegmachen sollst und statt dessen
Code:
matrix.length
nehmen.
Die 2. Methode macht auch kein Sinn:
1. gibst du nichts zurück
2. greifst du wieder gar nicht auf die Werte zu, die man der Methode übergibt
3. wieder irgendwelche auf der Luft gegriffenen Zahlen.
 

Jo.Mo.

Aktives Mitglied
...warum ist die if-abfrage sinnfrei? Das noch nichts drinsteht ist mir bewusst, ich muss ja erstmal sehen was ich in der mainMethode übergebe um zu sehen auf was ich das prüfe. Es geht darum, dass bei unmöglichkeit einer Multiplikation "null" zurückgegeben werden soll. Was wäre denn für dich sinnvoll?

2. Ich hatte den anderen Teil schon mal vor einiger Zeit gemacht, jetzt bloss reinkopiert, klar, dass noch nicht alles passt. Sitz ich wie gesagt dran.

3. Das hatte ich auch geschrieben, dass ich die main Methode dahingehend ändere.

Kann es sein, dass ihr "Profis" eine Art Tunnelblick für Java-Codes entwickelt und den Rest in den Posts ignoriert...? ;)
 

XHelp

Top Contributor
Kann es sein, dass ihr "Profis" eine Art Tunnelblick für Java-Codes entwickelt und den Rest in den Posts ignoriert...? ;)
Nö, in deinem Post hieß es ja:
...irgendwelche Verbesserungsvorschläge?
Also wurde es ja doch nicht ignoriert.
Und wenn du weißt, dass die Methode syntaktisch falsch ist, wenn du weißt, dass die semantisch falsch ist, wenn du weißt, dass du die noch ändern wirst: warum postest du die überhaupt? oO

Deine Prüf-Methode prüft ob es eine Dreiecksmatrix ist und gibt entweder true oder false zurück. Da gibt es kien null... Und da kann es auch kein null geben, weil boolean nicht null sein kann.
 

Jo.Mo.

Aktives Mitglied
Java:
public class MatrixOperation {

    	public static boolean pruefe (int[][] matrix) {

    		//if (){
    		   // return null;

    		//} else {
    			for (int i = 0; i < matrix.length; i++) {

                   for (int j = 0; j < i; j++) {

                       if(matrix[i][j] != 0)
                         return false;
                   }// for j
              } return true; // for i
              //}
    	}

        public static int[] matVek(int[][]matrix, int[]vektor) {

            int ergebnis[][] = new int[][];
            for(int i = 0; i < matrix.length; i++) {
			    for(int j = 0; j < vektor.length-1; j++) {
				    for(int k = 0; k < vektor.length; k++){

					ergebnis[i][j] += array[i][k]*vektor[k][j];
				    }
			    }
            }
        }



    public static void main(String[] args) {


         // Vereinbarungen
	     stdin in = new stdin();
	     int zeilen, spalten;
	     int[][]matrix;
	     int ergebnis[][];
	     int[] vektor;

	     // Eingabe der Anzahl Zeilen + Spalten Matrix
	     System.out.println("Bitte Matrix eingeben\n");
	     zeilen = in.getInt("Wieviele Zeilen hat die Matrix: ");
	     spalten = in.getInt("Wieviele Spalten hat die Matrix: ");

         // Reservierung des Speicherplatzes der Matrix
         matrix = new int[zeilen][spalten];

  	     // Eingabe der Elemente der Matrix
	     for (int i = 0; i<zeilen; i++) {
		     for (int j = 0; j<spalten; j++) {
			     matrix[i][j] = in.getInt("  Eingabe von ["+i+"]["+j+"] ");
		     } // for j
	     } // for i

	     // Eingabe der Anzahl Zeilen + Spalten Vektor
	     System.out.println("Bitte Vektor eingeben\n");
	     zeilen = in.getInt("Wieviele Zeilen hat der Vektor: ");

         // Reservierung des Speicherplatzes des Vektors
         vektor = new int[zeilen];

  	     // Eingabe der Elemente des Vektors
	     for (int i = 0; i<zeilen; i++) {
		      vektor[i] = in.getInt("  Eingabe von ["+i+"]");
		 } // for i




	  System.out.print(" "+ergebnis[i][j]);


    }


}

Ich bin zwar noch nicht fertig, aber über zielführende Kritik und verbesserungsvorschläge bin ich dankbar. :)

EDIT: @XHelp, danke, problem ist einfach, dass die Aufgabenstellung derart "lose" ist, dass es mir (und auch anderen Kommilitonen) schwer fält zu erkennen welche Form das Programm überhaupt annehmen soll. Die Zwischenergebnisse habe ich gepostet, um zu zeigen wie ich das löse. Der profi sieht da sicher fehler und kann dann rufen, halt, stopp. (passiert nur kaum)

Zur Multiplikation mit einem Vektor, hier mal die Aufgabenstellung:

Eine Methode int[] matVek(int[][]m, int[]v), die eine Matrix mit einem Vektor
multipliziert und den Ergebnisvektor zurückgibt. Falls die Multiplikation nicht möglich ist, soll
die Referenz null zurückgegeben werden.

...tollerweise haben wir die Fehlerbehandlung gerade erst angefangen bzw. nur grob behandelt. Ob und in welcher Form das nun verwendet werden soll hat man uns auch nicht mitgeteilt, aber mit den throwsException bin ich noch nicht firm...
 
Zuletzt bearbeitet:

XHelp

Top Contributor
Selbst in der Aufgabenstellung steht, dass du eine Ergebnisvektor hast... Weißt du denn, wie du eine Matrix mit einem Vektor multiplizierst? Genau so wie du es auf dem Papier machst, musst du es auch in Java umsetzen.
Und die Rückgabe von null bezieht sich wohl offensichtlich auch auf die matVek-Methode, deswegen weiß ich nicht so ganz, was es in deiner Prüf-Methode zu suchen hat...
 

Jo.Mo.

Aktives Mitglied
Shice...ja das kommt davon wenn man nicht richtig auf die Aufgabenstellung schaut...ich änder es gerade...

Matrix mal Vektor...da habe ich jetzt in einem Java-Schmöker ein beispiel gefunden...

Java:
	public Matrix multiply (Matrix B) {
    		if (this.n != B.getRowDim())
    			throw new IllegalArgumentException ("Matrix-Dimensionen nicht korrekt!");

    		int m = this.getRowDim();
    		int n = B.getColumnDim();
    		double[][] newElems = new double[m][n];
    		double[][] elemsB = B.getArray();
    		double sum = 0;

    		for (int i = 0; i < m; i++) {
    			for (int j = 0; j < n; j++) {
    				sum = 0;
    				for (int k = 0; k < this.getColumnDim(); k++)
    					sum += this.elems[i][k] * elemsB[k][j];
    				newElems[i][j] = sum;
    			}
    		}

    		return new Matrix(m, n, newElems);
        }

die bezeichnungen passen zwar nicht, ich probiere gerade zu entschlüssen was die Sachen bewirken und das für meinen Fall abzuändern.
 

Neue Themen


Oben