Pythons Modul 'random' hat eine Funktion random.choice
erhöht
random.choice(seq)
Liefert ein zufälliges Element aus der nicht leeren Sequenz seq. Wennseq
leer ist, wirdIndexError
.
Wie kann ich das in .NET emulieren?
%Vor%Edit: Ich habe das vor einigen Jahren als Interviewfrage gehört, aber heute trat das Problem natürlich in meiner Arbeit auf. Die Interviewfrage wurde mit Einschränkungen angegeben.
Um eine Methode zu erstellen, die die Quelle nur einmal iteriert und nicht temporär Speicher reservieren muss, zählen Sie, wie viele Elemente Sie iteriert haben, und bestimmen Sie die Wahrscheinlichkeit, dass das aktuelle Element das Ergebnis sein soll:
%Vor%Wenn Sie beim ersten Element sind, ist die Wahrscheinlichkeit 1/1, dass es verwendet werden sollte (da dies das einzige Element ist, das Sie bisher gesehen haben). Wenn Sie am zweiten Element sind, ist die Wahrscheinlichkeit 1/2, dass es das erste Element ersetzen soll usw.
Dies wird natürlich ein bisschen mehr CPU verbrauchen, da es eine Zufallszahl pro Element erzeugt, nicht nur eine einzelne Zufallszahl, um ein Element auszuwählen, wie dasblinkenlight gezeigt hat. Sie können überprüfen, ob die Quelle IList<T>
implementiert, wie Dan Tao vorgeschlagen hat, und eine Implementierung verwenden, die die Funktionen verwendet, um die Länge der Auflistung abzurufen und Elemente nach Index abzurufen:
Hinweis: Sie sollten in Erwägung ziehen, die Random
-Instanz in die Methode zu senden. Andernfalls erhalten Sie den gleichen zufälligen Startwert, wenn Sie die Methode zwei Mal zu nahe an der Zeit aufrufen, da der Startwert aus der aktuellen Zeit erstellt wird.
Das Ergebnis eines Testlaufs, bei dem eine Zahl aus einem Array ausgewählt wird, die 0 - 9, 1000000 Mal enthält, um zu zeigen, dass die Verteilung der ausgewählten Zahlen nicht verzerrt ist:
%Vor%Um zu vermeiden, dass Sie die Sequenz zweimal durchlaufen (einmal für die Zählung und einmal für das Element), ist es wahrscheinlich eine gute Idee, Ihre Sequenz in einem Array zu speichern, bevor Sie ihr zufälliges Element erhalten:
%Vor%BEARBEITEN Implementiert eine sehr gute Idee von Chris Sinclair .
Ich würde mit Antwort von dasblinkenlight gehen, mit einer kleinen Änderung: Nutzen Sie die Tatsache, dass source
bereits sein könnte eine indizierte Sammlung. In diesem Fall müssen Sie wirklich kein neues Array (oder keine neue Liste) auffüllen:
Beachten Sie, dass ich auch die Schnittstelle von der oben genannten Antwort geändert habe, um sie konsistenter zu der Python-Version zu machen, auf die Sie in Ihrer Frage verwiesen haben:
%Vor%Bearbeiten Ich mag Guffas Antwort sogar noch besser.
Nun, hole eine Liste aller Elemente in der Sequenz. Fragen Sie einen Zufallszahlengenerator für den Index, geben Sie die Elemente nach Index zurück. Definieren Sie, welche Sequenz - IEnumerable am offensichtlichsten ist, aber Sie müssen diese in eine Liste materialisieren und dann die Anzahl der Elemente für den Zufallszahlengenerator kennen. Das ist übrigens nicht emulieren, es ist implementieren.
Ist das eine Hausaufgaben-Anfänger-Kurs-Frage?