Java Doppelte Zufallszahl verhindern?
Baue ein Lotto-Programm nach und das ist das Letzte, was mich blockiert: Manchmal kommen doppelte Lottozhalen, raus obwohl ich dieses "doppelte Zahl" Auffang-Netz
gebaut habe. Funktioniert es nicht oder kann man es verbessern?
Meine Vorstellung wie ich es machen wollte:
(Zufallszahl wird erzeugt und in nächsten Arry platz reingeschrieben) x 6
Durch die doppelten for schleifen werden die array plätze untereinander verglichen
durch die if schleife wird jedes mal, wenn ein Paar gefunden wird doppelt um eins erhöht
Am ende wiederholt sich die schleife wenn doppelt nicht null ist bis Zahlen rauskommen, die nicht doppelt sind
Zum Schönen Anschauen:
Zum kopieren:
String [] LottoZahlen = new String [6];
int doppelt;
int zufall;
do {
doppelt = 0;
for(int i = 0; i<6; i++) {
zufall = (int)(Math.random() * 49);
zufall = zufall + 1;
LottoZahlen[i] = String.valueOf(zufall);
}
for(int i = 0; i<1; i++) {
for(int ao = 0; i<6; i++) {
if (LottoZahlen[i].equals(LottoZahlen [ao])) {
doppelt++;
}
}
}
}while (doppelt == (int) 0);
6 Antworten
Bei der zweiten (doppelten) for-Schleife, gehst du nicht über alle Elemente, sondern nur über das erste und vergleichst das mit den restlichen, das ist schon mal nicht ganz richtig, denn es könnte ja die zweite und die dritte Zahl gleich sein.
Du musst also alle Kombinationen, also der Einfachheit 6*6 überprüfen, ersetze also durch:
for(int i = 0; i<6; i++) {
for(int j=0; j<6; j++) {
if (LottoZahlen[i].equals(LottoZahlen [j])) {
doppelt++;
}
}
}
Jetzt musst du aber zusätzlich aufpassen, denn es wird ja dann jede Kombination überprüft, auch die Zahl mit sich selber. Initialisiere also doppelt als -6, oder füge noch if(i!=j) hinzu.
Ganz unten müsste auch dann while(doppelt!=0) stehen, denn du willst ja so lange weiter machen, bis eben keine doppelten mehr drin sind.
So könnte der Code am Ende aussehen:
String [] LottoZahlen = new String [6];
int doppelt;
int zufall;
do {
doppelt = 0;
for(int i = 0; i<6; i++) {
zufall = (int)(Math.random() * 49);
zufall = zufall + 1;
LottoZahlen[i] = String.valueOf(zufall);
}
for(int i = 0; i<6; i++) {
for(int j=0; j<6; j++) {
if (LottoZahlen[i].equals(LottoZahlen [j])&&(i!=j)) {
doppelt++;
}
}
}
} while (doppelt != 0);
System.out.println(Arrays.toString(LottoZahlen));
Ein paar Tipps:
- Mach doch das Array gleich vom Typ Integer, wenn da nur Zahlen reinkommen, dann sparst du dir die Konvertierung
- 0 musst du nicht in einen int casten
- Statt zufall = zufall + 1; kannst du auch zufall++; benutzen.
Es gibt übrigens auch einen Datentyp, der automatisch keine Duplikate enthält, und die Werte sortiert, falls du das professionell brauchst. Für eine Übung natürlich etwas langweilig:
import java.util.HashSet;
import java.util.Set;
Set<Integer> lottoZahlen = new HashSet<>();
lottoZahlen.add(3);
lottoZahlen.add(1);
lottoZahlen.add(2);
lottoZahlen.add(3);
System.out.print(lottoZahlen);
//[1, 2, 3]
Mal noch eine kleine Ergänzung, mit Java 8 Streams geht es auch so:
List<Integer> randomValues = new Random().ints(1, 50)
.distinct()
.limit(6)
.boxed()
.sorted()
.collect(Collectors.toList());
Falls die Sortierung nicht notwendig ist, kann man das ".sorted()" auch weglassen.
3 dinge.
1. Du wiederholst das ganze nur wenn es KEINE doppelten zahlen gibt. Dabei willst du es doch bestimmt wiederholen WENN es doppelte zahlen gibt.
2. Die äussere schleife mit i bei der prüfung auf doppelte zahlen vergleicht nur die erste zahl mit den anderen. Ob aber zahlen 4 und 6 gleich sind wird nie geprüft.
3. doppelt wird niemals null sein. Denn wenn i und ao 0 sind. Ist die IF logischerweise immer true.
Mach folgendes:
Alles weg bis auf deine Zufallszahlen schleife.
Dann nachdem du eine Zufallszahl dir geholt hast.
Prüfst du ob DIESE eine zufallszahl schon im array ist. (Array durchlaufen und diese zahl prüfen)
Falls ja. Das ganze ab der Zufallszahl wiederholen. (Noche zufallszahl holen und nochmal prüfen. Solange bis du eine hast die noch nicht vorhanden ist)
Okay. Sehr scharfer Blick :D Ich versuch das mal und meld mich wieder :))
zufall = (int)(Math.random() * 49);
zufall = zufall + 1;
Da kann übrigens 50 rauskommen.
Math Radom reicht mit sicherheit von 0-1 also ist 1 auch ein möglicher wert. Entsprechend kann 49 herauskommen. Welches du dann um eins rauf zählst.
ist mir noch nie passiert aber ok. Ändere ich und teste dann wieder
Habe mich geirrt. 1.0 gehört nicht zum wertebereich von Math.Random()...
Ist also mist was ich gesagt habe.
Ich würde in einem Array/std::vector die Zahlen 1-49 speichern und immer wieder ein zufälliges Element wählen und danach die Zahl aus dem Array/std::vector löschen.
Abfragen, ob es die Zahl schon gibt und wenn ja, nochmal "würfeln" :-)
Wie? Ich versuche das doch eh mit dieser Schleife. Wenn ein wert doppelt ist, wird nochmal gewürfelt und wieder geprüft.
LG
Probiere ich auch! Danke:))