Methoden Lotto mit sechs richtigen

klhlubek

Mitglied
Hey Leute,

ich habe ein kleines Problem mit der Verständlichkeit eines Java Codes für die Ziehung von sechs richtigen Lottozahlen aus meinem Buch und zwar bin ich ja neu hier und möchte daher näher betonen, dass ich schon versucht habe dieses Problem (der Code ist richtig doch ich verstehe eine for Schleife nicht) zu lösen.

Java:
import java.util.Arrays;
import java.util.Random;

public class Lotto {

  public static void main(String[] args) {
    int[] tipp = {1, 4, 8, 22, 23, 48};
    int[] ziehung;
    long n=0;
    
    // Schleife, so oft Lotto spielen, bis die sechs Zahlen übereinstimmen
    do {
      n++;
      ziehung = gewinnzahlen();  
    } while( Arrays.equals(tipp, ziehung)==false );
   
    System.out.format("Sechs richtige Zahlen nach nur %d Jahren!\n", n/100);
  }

  public static int[] gewinnzahlen() {
    int[] ziehung = new int[6];
    int zahl;
    Random r = new Random();
    int n=0;

    // Schleife für alle sechs Zahlen
    do {
      zahl = 1 + r.nextInt(49);
      // testen, ob Doppelgänger
      for(int i=0; i<n-1; i++) {       // HIER IST DIE SCHLEIFE!
        if(ziehung[i] == zahl)
          continue;  // Schleifendurchgang wiederholen   
      }
      ziehung[n]=zahl;
      n++;
    } while(n<6);
    
    Arrays.sort(ziehung);
    return ziehung;
  }
  
}

Nun meine Frage zu dieser Schleife (habe sie mit einem Kommentar markiert):

Wieso ist den der Test hier "true", denn ich denke das er ja "false" ist und die Schleife somit abbricht.
Noch eine Info: Diese Schleife ist für das Kontrollieren auf eine doppelte Zahl im Lotto da und deswegen muss es ja überprüfen ob es schon dieselbe Zahl existiert.

Es wäre nett wen ihr mir erklären könntet, wie den dieser Test der Schleife funktionieren soll.

Danke euch für die Antworten!!
 
Die äußere Schleife würde, wenn es die inenre nicht gäbe 6 Zufallszashlen in das Array Ziehung[] packen.
Bei jeder Zahl die in das Array gepackt wird, wird n um 1 erhöht um die nächste Zahl in den nächsten Indexslot zu stecken. Soweit ist das klar oder?

Nun wird nach dem Ermitteln einer Zahl einfach vin 0 bis n (sprich der bereits vorhandenen Zahlen im Array) getestet ob diese ermittelte Zahl bereits in einem Indexslot des Array steckt. Wenn ja, dann wird die Schleife nicht abgebrochen (dann würde da ein break stehen) sondern die Schleife von vornbe begonnen, ohne das die nachfolgenden Zeile noch abrgearbeitet werde. Es wird also weder die Zahl dem Array zugewiesen, noch wird n um eins erhöht. Die nächste ermittelte Zahl wird also immer noch in den gleichen Indexslot gestockt wie die vorher verworfene.

Gruß

Claus
 
Die äußere Schleife würde, wenn es die inenre nicht gäbe 6 Zufallszashlen in das Array Ziehung[] packen.
Bei jeder Zahl die in das Array gepackt wird, wird n um 1 erhöht um die nächste Zahl in den nächsten Indexslot zu stecken. Soweit ist das klar oder?

Nun wird nach dem Ermitteln einer Zahl einfach vin 0 bis n (sprich der bereits vorhandenen Zahlen im Array) getestet ob diese ermittelte Zahl bereits in einem Indexslot des Array steckt. Wenn ja, dann wird die Schleife nicht abgebrochen (dann würde da ein break stehen) sondern die Schleife von vornbe begonnen, ohne das die nachfolgenden Zeile noch abrgearbeitet werde. Es wird also weder die Zahl dem Array zugewiesen, noch wird n um eins erhöht. Die nächste ermittelte Zahl wird also immer noch in den gleichen Indexslot gestockt wie die vorher verworfene.

Gruß

Claus

Danke für die Antwort, aber was ich daran nicht verstehe ist, das bei dem ersten auslesen dieser schleife i = 0 und
n = 0 ist und die Bedingung der Schleife sagt ja i < n-1 und das würde ja 0 < -1 beim ersten auslesen ergeben, sodass sie ja abbrechen müsste.

Irgendwie vermute ich aber, dass ich in dem Code irgendetwas übersehe, sodass meine Frage sehr banal ist. Ich würde mich trotzdem über eine Erläuterung meines Fehlers in meiner Denkweise freuen.
 
Stimmt das ist tatsächlich ein Fehler. Es muss heißen i<n und nicht i<n-1. Allerdings ist dein denken trotzdem falsch. Im Fall von deinem Beispiel also 0<-1 würde die Schleife einfach gar nicht durchlaufen. Das beduetet mit dem Fehler werden die letzten beiden Zahlen tatsächlich nicht verglichen und können von daher gleich sein.

Gruß

Claus
 
Zuletzt bearbeitet:
Stimmt das ist tatsächlich ein Fehler. Es muss heißen i<n und nicht i<n-1. Allerdings ist dein denken trotzdem falsch. Im Fall von deinem Beispiel also 0<-1 würde die Schleife einfach gar nicht durchlaufen. Das beduetet mit dem Fehler werden die letzten beiden Zahlen tatsächlich nicht verglichen und können von daher gleich sein.

Gruß

Claus

Aber ich freu mich, dass dies tatsächlich ein Fehler war und nicht mein Unverständnis.
Dieser Fehler geht gleich an den Verlag. Wir wollen die Autoren ja unterstützen. 😉
 
Also ich finde auch mit der verbesserten Zeile (i < n) tuen die Schleifen noch nicht das was sie sollten.

Es ist überhaupt kein Unterschied, ob die gerade generierte Zufallszahl bereits im Array enthalten ist oder nicht. Denn sollte sie enthalten sein wird das "continue" ausgeführt. Das bewirkt aber nur dass die for Schleife an dieser Stelle aufhört und mit dem nächsten index (i) weiter macht. Anders ausgedrückt: Nachfolgende Zeilen in! der Schleife würden so übersprungen. Aber es stehen keine weiteren Zeilen in der Schleife, die abgearbeitet werden müssten.

Daraus folgt, dass mit diesem Code trotzdem doppelte/dreifache etc Zahlen in der Ziehung vorkommen können.

Ich bin mir zwar recht sicher, dass dem so ist, aber könnte das mal wer gegenchecken? Immerhin möglich, dass ich so früh in der Woche noch nicht so kompetent bin 🙂
 
Ui Du hast recht. Das Continue beendet ja die For Schleife und nicht die While Schleife. Das war wahrscheinlich die Intention des Authors, dass sich das Continue auf die While Schleife bezieht. Bin ich glatt mit drauf reingefallen

Gruß

Claus
 
Der vollständigkeit halber sei noch erwähnt: Es gibt ein Konstrukt mit dem dieser Code korrekt arbeitet. Man kann Label setzen mit denen die Schleifenabarbeitungen gesteuert werden können:

Java:
	 public static int[] gewinnzahlen()
	 {
		 int[] ziehung = new int[6];
		 int zahl;
		 Random r = new Random();
		 int n=0;
		 
		 // Schleife für alle sechs Zahlen
		 nochmal:
		 do
		 {
			 zahl = 1 + r.nextInt(49);
			 
			 // testen, ob Doppelgänger
			 for(int i = 0; i < n; i++)
			 { 
				 if(ziehung[i] == zahl)
					 continue nochmal; // Äußeren Schleifendurchgang (do-Schleife) wiederholen
			 }
			 
			 ziehung[n]=zahl;
			 n++;
		 }
		 while(n < 6);
		 
		 Arrays.sort(ziehung);
		 return ziehung;
	}

Ich persönlich habe so etwas bisher eher selten gebraucht. Vielleicht ein oder zweimal. Kommt immer auf das jeweilige Problem an, was man lösen möchte und natürlich auf die persönlichen Präferenzen.
 
Ich würde in dem Fall lieber eine boolean found einführen also:

Java:
 public static int[] gewinnzahlen()
	 {
		 int[] ziehung = new int[6];
		 int zahl;
		 Random r = new Random();
		 int n=0;
 
		 do
		 {
			 zahl = 1 + r.nextInt(49);
 
			 // testen, ob Doppelgänger
                         boolean found=false;
			 for(int i = 0; i < n; i++)
			 { 
				 if(ziehung[i] == zahl)
                                 {
                                         found=true;
                                         break;
                                 }
			 }
                         if(!found)
                         {
			     ziehung[n]=zahl;
			     n++;
                         }
		 }
		 while(n < 6);
 
		 Arrays.sort(ziehung);
		 return ziehung;
	}

Finde ich leserlicher

Gruß

Claus
 
Danke für das vorbildliche Verbessern dieses Fehlers und eure Codes ( Da sieht man auch einmal wie die Codes anderer Programmierer aussehen).

Persönlich: Ich muss wirklich zugeben, dass mir beide Lösung von euch gefallen, wie das Label als auch der Booleanwert.
 

Zurück
Oben