Kann mir jemand das Beispiel kurz erklären so ungefähr:/

[CODE lang="java" title="code"]private static void drawPatternRecursive(int x, int y, int l, boolean c) {
if (l >= 16) {


drawPatternRecursive(x + l / 4, y + l / 4, l / 2, !c);
drawPatternRecursive(x - l / 4, y - l / 4, l / 2, !c);
drawPatternRecursive(x - l / 4, y + l / 4, l / 2, !c);
drawPatternRecursive(x + l / 4, y - l / 4, l / 2, !c);

if (c) {
StdDraw.setPenColor(StdDraw.ORANGE);
//c = true;
} else {
StdDraw.setPenColor(StdDraw.BLUE);
//c = false;
}

StdDraw.filledRectangle(x, y, l * 0.05 / 2, l / 2);
StdDraw.filledRectangle(x, y, l / 2, l * 0.05 / 2);
}
}[/CODE]
 
Als erstes ist die Frage, was die Variablen bedeuten: x, y, l und c - das ist ja im Text erläutert.

- Dann ist die Frage, was der Code macht. Wenn Du das nicht verstehst, dann schau es Dir an. Kommentier die 4 rekursiven Aufrufe aus. Was macht dann die Methode?
- Dann nimm dir den ersten Rekursiven Aufruf und ruf diesen außerhalb auch noch auf. Du hast also einen Aufruf mit gewissen Werten und nun rufst Du den auf, wobei die Parameter verändert sind - und zwar so wie in dem ersten rekursiven Aufruf. -> Was macht er dann?
- Diesen Aufruf kommentierst Du aus und dafür nimmst Du den ersten rekursiven Aufruf rein. -> Was macht der Code nun?
- das schaust Du dann auch noch bei den anderen beiden Aufrufen, entweder jeweils mit auskommentieren der anderen rekursiven Aufrufe.
- Evtl. ist es hilfreich, wenn Du dann den Aufruf aus dem zweiten Punkt der Auflistung noch einmal dazu nimmst um zu betrachten, wie es sich ändert ...
- Nun kannst Du die die auskommentierten Codes nach und nach hinzu nehmen und das zusätzlich hinzugefügte weg und voila: Das ganze Bild entsteht und du hast hoffentlich verstanden, was diese rekursive Methode macht.
 
Lass gedanklich erstmal die Zeilen 5 bis 8 raus, d. h. lass die Rekursion weg. Dann passiert ja offensichtlich folgendes:

Wenn l < 16 ist, ist das Thema erledigt. Ansonsten wird geprüft, ob c true ist. Ist dies der Fall, wird der Stift auf orange gesetzt, sonst auf blau. Naja und dann werden zwei Rechtecke mit dem Mittelpunkt (x,y) gezeichnet: einmal vertikal (Zeile 18) und einmal horizontal (Zeile 19). Die Höhe bzw. Breite ist dabei l/2, die Breite bzw. Höhe 5 % davon.

Das kann man mal durchspielen für den Aufruf aus der Aufgabenstellung: x und y sind 0. Die Länge ist 512 und das c steht auf true. Also werden zwei orangene Rechtecke der Länge 256 über Kreuz mit Mittelpunkt (0,0) gezeichnet.

Jetzt bauen wir mal Zeile 5 ein. Dann wird - noch bevor die Stiffarbe einegestellt wird und die 256er-Rechtecke gezeichnet werden - die Methode erneut aufgerufen. Aber natürlich mit anderen Parametern: Der Mittelpunkt wird horizontal nach rechts und vertikal nach unten um 1/4 der angegebenen Länge verschoben. Dort sollen Rechtecke mit der halben bisherigen Länge gezeichnet werden. Der Farbparameter wird negiert, so dass sich bei jedem wiederkehrenden Aufruf die Farbe ändert.

Das kann man wieder durchspielen:
Ebene 1: Parameter: 0, 0, 512, true
Test in Zeile 2 liefert true, also wird mit Zeile 5 fortgefahren. Dort erfolgt nun ein neuer Aufruf:
Ebene 2: Parameter: 128, 128, 256, false
Test in Zeile 2 liefert true, also wird mit Zeile 5 fortgefahren. Dort erfolgt nun ein neuer Aufruf:
Ebene 3: Parameter: 160, 160, 128, true
Test in Zeile 2 liefert true, also wird mit Zeile 5 fortgefahren. Dort erfolgt nun ein neuer Aufruf:
Ebene 4: Parameter: 168, 168, 64, false
Test in Zeile 2 liefert true, also wird mit Zeile 5 fortgefahren. Dort erfolgt nun ein neuer Aufruf:
Ebene 5: Parameter: 184, 184, 32, true
Test in Zeile 2 liefert true, also wird mit Zeile 5 fortgefahren. Dort erfolgt nun ein neuer Aufruf:
Ebene 6: Parameter: 192, 192, 16, false
Test in Zeile 2 liefert true, also wird mit Zeile 5 fortgefahren. Dort erfolgt nun ein neuer Aufruf:
Ebene 7: Parameter: 200, 200, 8, true
Test in Zeile 2 liefert false, damit ist der Methodenaufruf aus Ebene 6 beendet.
Ebene 6: Code wird ab Zeile 10 weiter ausgeführt (die anderen Zeilen haben wir ja ausgeblendet)
Die Parameter auf Ebene 6 waren: 192, 192, 16, false. Also werden jetzt blaue Rechtecke mit Mittelpunkt 192,192 der Länge 8 gezeichnet. Damit ist der Methodenaufruf aus Ebene 5 beendet.
Ebene 5: Code wird ab Zeile 10 weiter ausgeführt (die anderen Zeilen haben wir ja ausgeblendet)
Die Parameter auf Ebene 5 waren: 184, 184, 32, true Also werden jetzt orange Rechtecke mit Mittelpunkt 184,184 der Länge 16 gezeichnet. Damit ist der Methodenaufruf aus Ebene 4 beendet.
usw.

EDIT: Wenn Du jetzt Zeile 6 einbaust, funktioniert das nach dem gleichen Prinzip, d. h. nach einer Rückkehr des Methodenaufrufs aus Zeile 5 erfolgt sofort der nächste Aufruf in Zeile 6 und erst, wenn dieser zurückkehrt, geht es auf der gleichen Ebene mit der nächsten Zeile weiter.
 
[CODE lang="java" title="iterative MEthode"]private static void drawPatternIterative(int width) {
int length = width/64;
// boolean c = false;
boolean c = true;

for ( int x=0; x<6; x++){
if(c){
StdDraw.setPenColor(StdDraw.BLUE);
c=false;
}else {
StdDraw.setPenColor(StdDraw.ORANGE);
c=true;
}
for(int y = 1; y< width/length; y++){
for(int z=1; z<width/length;z++){
StdDraw.filledRectangle(-256+length*z,-256+length*y,length,length*0.05);
StdDraw.filledRectangle(-256+length*z,-256+length*y,length*0.05, length);
}
}
length*=2;
}
}[/CODE]

kann mir jemand noch das kurz erklären, vielen dank für das davor, das ist die iterative methode warum steht da 64 am anfang
 
Also ich bezweifle, dass diese iterative Methode das Gleiche macht wie die Rekursive Methode.

Wenn dem so wäre, dann müsste es ja etwas geben wie ein Aufruf nur mit der breite, welche dann die Rekursive Methode aufruft mit entsprechenden Dingen ...

Der Unterschied wird auch schnell deutlich:
width wird vorgegeben
length = width/64

Die Schleife läuft von 1 bis width/length = width/(width/64) = 64
==> Es gibt also eine fixe Anzahl an Kreuze, die Gemalt werden.

Bei der Rekursion war dies abhängig vom Parameter l. Wenn der Parameter l < 16 ist, dann wird nichts gemalt und ansonsten n Mal wenn gilt
16*2^(n-1) <= l < 16*2^n
Das kommt, weil ja immer / 2 gerechnet wird. l < 16: 0, 16-31: 1, 32-63: 2, ...

Dadurch ist dies erst einmal ein unterschiedliches Verhalten und ich sehe nicht, dass es hier wirklich um den gleichen Algorithmus geht.

Aber das war jetzt auch nur ein schneller, kurzer Blick - vielleicht irre ich mich ja auch und habe etwas übersehen ...
 

Zurück
Oben