Erzeugung von nicht-wiederholende Zufallszahlen in JS
Habe ich die folgende Funktion
function randomNum(max, used){
newNum = Math.floor(Math.random() * max + 1);
if($.inArray(newNum, used) === -1){
console.log(newNum + " is not in array");
return newNum;
}else{
return randomNum(max,used);
}
}
Grundsätzlich erstelle ich eine zufällige Zahl zwischen 1 - 10 und überprüfen, um zu sehen, wenn diese Zahl bereits erstellt wurde, indem es ein array und überprüfen Sie die neu erstellte Anzahl gegen Sie. Ich nenne es, indem es eine variable..
UPDATED:
for(var i=0;i < 10;i++){
randNum = randomNum(10, usedNums);
usedNums.push(randNum);
//do something with ranNum
}
Dies funktioniert, aber im Chrome bekomme ich folgende Fehlermeldung:
Uncaught RangeError: Maximum call stack size exceeded
Denen ich denke, es ist weil ich bin dem Aufruf der Funktion in sich selbst zu oft. Was bedeutet mein code ist nicht gut.
Kann mir jemand helfen mit der Logik? was ist eine beste Weg, um sicherzustellen, dass meine zahlen nicht wiederholen?
Anstelle von Rekursion, die Sie könnten versuchen, mit einer Schleife statt. Möglicherweise möchten Sie jedoch, vorstellen, eine gewisse Logik zu prüfen nur den Betrag x-mal. Dies ist allgemein bekannt als der Halteproblem.
InformationsquelleAutor | 2013-09-14
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wenn ich verstehe, richtig ist, dann sind Sie nur auf der Suche nach einer permutation (d.h. die zahlen randomisierten ohne Wiederholungen) von den zahlen 1-10?
Vielleicht erzeugen Sie eine randomisierte Liste dieser Nummern, einmal zu Beginn, und dann, nur arbeiten Sie Ihren Weg durch die?
Dieser berechnet eine zufällige permutation der zahlen in
nums
:So, zum Beispiel, wenn Sie waren auf der Suche für Zufallszahlen zwischen 1 - 20, die waren auch noch, dann könnte man verwenden:
Dann Lesen Sie einfach durch
ranNums
um zu erinnern, der Zufallszahlen.Läuft keine Gefahr, es nehmen immer mehr zu finden, ungenutzte zahlen, als Sie fanden, dass in Ihrem Ansatz.
BEARBEITEN: Nach der Lektüre diese und ausführen eines Tests auf jsperf, wie es scheint, ein viel besserer Weg, dies zu tun, ist ein Fisher–Yates-Shuffle:
Grundsätzlich ist es effizienter, die durch die Vermeidung der Verwendung von 'teuer' array-Operationen.
BONUS BEARBEITEN: eine Andere Möglichkeit ist die Verwendung Generatoren (vorausgesetzt, Sie haben Unterstützung):
Dann zu verwenden:
wo
ranNums.next().value
schließlich bewerten zuundefined
sobald Sie laufen durch alle Elemente in dem gemischten array.Insgesamt nicht so effizient wie der Fisher–Yates-Shuffle, denn du bist immer noch
splice
-ing ein array. Aber der Unterschied ist, dass Sie jetzt tun, dass die Arbeit nur, wenn Sie es brauchen, anstatt alles im Voraus, so dass je nach Anwendungsfall, diese könnte besser sein.InformationsquelleAutor Ben Jackson
Das Problem ist, dass, wie Sie nähern sich der Sättigung, die Sie beginnen, mehr und mehr zu generieren, die eine eindeutige Nummer, die "zufällig". Zum Beispiel, im Beispiel oben ist das max 10. Sobald die verwendete Zahl-array enthält 8 zahlen, kann es möglicherweise eine lange Zeit für die 9. und 10 gefunden werden. Dies ist wahrscheinlich, wo das maximum call stack-Fehler generiert wird.
jsFiddle Demo zeigt Iterationszähler wird ausgereizt
Durch Durchlaufen innerhalb Ihrer Rekursion, können Sie sehen, dass ein großer Teil der Ausführung tritt auf, wenn das array vollständig gesättigt, aber die Funktion aufgerufen wird. In diesem Szenario wird die Funktion verlassen.
jsFiddle Demo mit dem frühen break
Einer letzten Weg zu erreichen, sowohl die iteration überprüft, und das eine unendliche Rekursion wäre, wie dies
jsFiddle Demo
:Siehe edits und demos. Grundsätzlich sollte man schützen, gegen die eine unendliche Rekursion oder eine große Menge findet im Falle einer hohen Nummer ist für max.
InformationsquelleAutor Travis J
Dies zu tun, was Sie suchen:
Haben wir:
Diese Funktion wird:
Weil der guard-Klausel (
if (arr.length >= 10) return;
), die Funktion wird nicht weiter ausgeführt, sobald der Parameter erfüllt worden sind.InformationsquelleAutor Stephen Hodges
Gebaut, ein bisschen testen, versuchen, diese auf jsfiddle:
Shuffle-Funktion mit freundlicher Genehmigung von dzone.com.
InformationsquelleAutor Niccolò Campolungo
Dies ist, wie ich es erreichen mit underscore.js
Bekommen
n
zahlen vonmin
zumax
Werte. Won
ist diesize
argument.InformationsquelleAutor Carlo Rodríguez
InformationsquelleAutor Mayank Sudden
Sorry das ist eine neue Antwort auf eine alte Frage, aber dies kann mehr effizient mit einer Karte. Was Sie nach ist die zufällige Auswahl eher als nicht-Wiederholung random. Nicht wiederholen, zufällig, unsinnig.
Denen _a ist die Sammlung, und r ist nicht Teil der Sammlung, die wir lambda der Zufallswert r:
Neu definieren aRandom._a, wenn der browser wird träge. Um zu vermeiden, eventuelle Trägheit, sollte man wirklich nutzen eine UUID generation algo mit ausreichend Entropie, so dass die Chancen der Wiederholung werden effektiv null ist, anstatt brute Force Differenzierbarkeit. Ich wählte den Namen der Funktion aRandom, denn die lateinische Vorsilbe A - bedeutet "Weg von". Seit den mehr Sie verwendet werden, die weiter entfernt von zufällige Ausgabe. Die Funktion liefert eine million eindeutige Werte in 2100 ms auf einem Macbook.
Vorteil der oben genannten Lösung ist keine Notwendigkeit, die Grenze gesetzt. Wie gut, mehrere Anrufer können es verwenden, zur gleichen Zeit, und übernehmen deren Werte unterscheiden sich von allen anderen Anrufern. Dies ist nützlich für Dinge wie Rauschen Jitter-Verteilungen mit versichert keine überschneidungen.
Aber es kann geändert werden, um ganze zahlen zurückzugeben, sowie, so zu beschränken, ram zu verwenden, um die Länge geliefert:
InformationsquelleAutor Radio
Du möchtest nicht wirklich eine verloren von Zufallszahlen. Echte Zufallszahlen müssen in der Lage sein, Sie zu wiederholen.
Wirklich Zufallszahlen sind wie würfeln. Jede Zahl kommen kann neben.
Gemischt zahlen sind wie beim Karten spielen. Kann jede Zahl kommen nur einmal.
Was Sie wirklich fordert, ist die shuffle-eine Liste von zahlen, und verwenden Sie dann den ersten so viele zahlen aus dem gemischten Liste.
Denken, eine Liste von zahlen in Ordnung, und dann mit Hilfe der random number generator, um nach dem Zufallsprinzip wählen Sie eine Nummer aus einer Kopie der Liste. Jedes mal, legen Sie die ausgewählte Nummer an das Ende der neuen Liste und entfernen Sie es von der Kopie von der alten Liste, die Verkürzung, die Liste. Wenn Sie fertig sind, die neue Liste enthält die gemischten zahlen und die Kopie der alten Liste leer.
Alternativ können Sie die Nummer ausgewählt haben und verwenden Sie es sofort, Verkürzung der Kopie von der Liste entfernen, die verwendet Anzahl. Denn Sie haben entfernt die Nummer aus der Liste, kann es nicht wieder hoch.
InformationsquelleAutor midimagic