In Java einen Array zahlen zuweisen wie?
ich habe ein Array aus 18 Feldern... nun möchte ich diesen 18 Feldern entsprechend eine zufällige Zahl zwischen 0-19 zuweisen... allerdings soll jede Zahl nur einmal vergeben werden. Prinzipiell wäre das ja mit Random und einer Schleife kein Problem... nur hat jemand eine Idee, wie ich überprüfen kann ob die entsprechende zufällige Zahl schon da ist? Oder kann ich gewisse Zahlen irgendwie ausschließen?
4 Antworten
Du kannst natürlich in der Schleife über das Array iterieren und prüfen, ob die Zahl schon existiert. Das führt aber zu quadratischer Laufzeit.
Dazu kommt, dass gegen Ende des Arrays, wenn nur noch wenig Zahlen übrig sind, das Programm so lange raten muss, bis es durch Zufall eine Zahl findet, die noch nicht existiert. Im Worst Case geht die Laufzeit also gegen Unendlich.
Eine bessere Lösung ist daher, die Zahlen in aufsteigender Reihenfolge einzufügen, und das Array danach mischen. Zum Mischen können wir folgende Methode verwenden:
public static void shuffle(int[] array) {
int len = array.length;
Random random = new Random();
for (int i = 0; i < len; ++i) {
// Wähle einen zufälligen Index >= i:
int index = i + random.nextInt(len - i);
// Tausche die Werte bei i und index:
int temp = array[i];
array[i] = array[index];
array[index] = temp;
}
}
Das einzige Problem ist, dass wir zwei Zahlen überspringen müssen: Das Array ist 18 lang, es gibt aber 20 mögliche Zahlen (0 bis 19).
Das können wir lösen, indem wir ein Array mit den Zahlen von 0 bis 19 erzeugen, dann mischen, und dann die ersten 18 Elemente davon in ein neues Array kopieren:
public static int[] makeArray() {
// Array mit Zahlen von 0 bis 19:
int[] array = IntStream.rangeClosed(0, 19).toArray();
// Mischen:
shuffle(array);
// Die ersten 18 Elemente davon kopieren:
int[] result = new int[18];
System.arraycopy(array, 0, result, 0, 18);
return result;
}
Fertig!
Ich hab nochmal ne Frage: angenommen ich würde jetzt auf dieses Array über Buttons zugreifen wollen... Also z.B. Im Programm wird auf Button 1 geklickt und dann gibt Button 1 den Wert der auf dem Array[0] liegt zurück, sodas dann der Wert verarbeitet werden kann.... wie kann ich das dann realisieren? Also im Controller der FXML Datei einfach den Button ansprechen lassen und den Wert vom Array zurück geben oder wie? Wenn ich das Array in der Main erstelle, findet dann der Controller das Array überhaupt?
Tut mir leid, mit JavaFX kenne ich mich nicht aus :(
Alles gut, trotzdem danke für deine Hilfe... dein Programm hat mir erstmal sehr geholfen
Mach dir ein already_used Array, wo du dann die schon benutzten Zahlen speicherst. Bevor du dann einen neuen Wert zuweist guckst du, ob dieser schon da drin ist. Wenn ja, ziehst du einen anderen.
Ist sicher nicht das effizienteste, aber mein erster Gedanke.
Oder du gehst stattdessen von 1-18 und suchst dir dann ein leeres Feld, um die Zahl darin zu speichern.
War auch mein zweiter Gedanke ^^. Leider gibt es keine vorhandene Methode :/
So eine Methode kannst du auch selber schreiben. Sonst zweiter Vorschlag.
Danke für eure Tipps... ich denke ich werde mir ein already_used Array anlegen
(ungetestet)
int zufall(int min, int max) {
int r = Math.floor(Math.random() * ((max - min) + 1) + min);
return r;
}
public void zuweisen() {
for (int i = 0; i < array.length; i++) {
int zuf = zufall(0, 19);
if (array(zuf) == -1) {
array[i] = zuf;
}
else {
i--;
}
}
}
Es wird geprüft, ob die Zahl nicht bereits vorkommt (,,== -1"), sonst wird eine neue für das Feld gesucht.
Du kannst in der Schleife eine weitere Schleife für das Überprüfen schreiben. Geht einmal durch den Array durch und überprüft, ob die Zahl schon existiert. Wenn es existiert kannst du den Counter in der äußeren Schleife um 1 veringern, um dennoch alle Arrayfelder zu füllen.
Wow, stimmt das Problem habe ich mir noch gar nicht so vor Augen geführt. Das wäre mir dann sicherlich beim fertigen Spiel aufgefallen, wenn es ewig geladen hätte...
ich glaube ich nehme mich deiner Lösung mal an
vielen Dank