Dies ist die SDK-Methode, nach der Sie suchen. Collections.shuffle (Arrays.asList (Array));
Louis Hong
2
@ Louie Nein, das funktioniert nicht. Das würde List<int[]>einen Eintrag mit einem Eintrag erstellen . Siehe meine Antwort für den Weg, um dies mit zu erreichen Collections.shuffle().
Duncan Jones
2
Keine wirkliche Antwort auf die ursprüngliche Frage, aber MathArrays.shuffle aus der commons-math3-Bibliothek erledigt den Job.
Sandris
1
Dies ist nicht thematisch genug, um eine Antwort zu rechtfertigen, aber ich erinnere mich an einen wirklich coolen Artikel aus dem Buch "Graphics Gems", in dem es darum ging, ein Array in pseudozufälliger Reihenfolge zu durchlaufen. In meinen Augen ist es besser, die Daten überhaupt erst mischen zu müssen. Die C-Implementierung finden Sie hier github.com/erich666/GraphicsGems/blob/master/gems/Dissolve.c
Die Verwendung von Sammlungen zum Mischen einer Reihe primitiver Typen ist ein wenig übertrieben ...
Es ist einfach genug, die Funktion selbst zu implementieren, indem Sie beispielsweise das Fisher-Yates-Shuffle verwenden :
import java.util.*;import java.util.concurrent.ThreadLocalRandom;classTest{publicstaticvoid main(String args[]){int[] solutionArray ={1,2,3,4,5,6,16,15,14,13,12,11};
shuffleArray(solutionArray);for(int i =0; i < solutionArray.length; i++){System.out.print(solutionArray[i]+" ");}System.out.println();}// Implementing Fisher–Yates shufflestaticvoid shuffleArray(int[] ar){// If running on Java 6 or older, use `new Random()` on RHS hereRandom rnd =ThreadLocalRandom.current();for(int i = ar.length -1; i >0; i--){int index = rnd.nextInt(i +1);// Simple swapint a = ar[index];
ar[index]= ar[i];
ar[i]= a;}}}
Extrem trivialer Nitpick, aber Sie können einfach println()statt verwenden println(""). Klarer in der Absicht denke ich :)
Cowan
55
Es wäre viel besser, Collections.shuffle (Arrays.asList (Array)) zu verwenden. dann mische dich selbst.
Louis Hong
21
@Louie Collections.shuffle(Arrays.asList(array))funktioniert nicht, weil die Arrays.asList(array)Rückkehr Collection<int[]>nicht so ist, Collection<Integer>wie Sie gedacht haben.
Adam Stelmaszczyk
15
@exhuma Denn wenn Sie ein Array von Tausenden oder Millionen primitiver Werte sortieren müssen, ist das Einschließen jedes einzelnen in ein Objekt, nur um eine Sortierung durchzuführen, sowohl im Speicher als auch in der CPU etwas kostspielig.
PhiLho
14
Dies ist nicht das Fisher-Yates-Shuffle. Dies nennt man Durstenfeld Shuffle . Das ursprüngliche Fisher-Yates-Shuffle läuft in O (n ^ 2) -Zeit, was extrem langsam ist.
Pacerier
164
Hier ist ein einfacher Weg mit ArrayList:
List<Integer> solution =newArrayList<>();for(int i =1; i <=6; i++){
solution.add(i);}Collections.shuffle(solution);
Sie können einfachCollectons.shuffle(Arrays.asList(solutionArray));
FindOutIslamNow
@Timmos Du liegst falsch. Arrays.asList umschließt das ursprüngliche Array und ändert es durch Ändern des ursprünglichen Arrays. Aus diesem Grund können Sie keine Arrays hinzufügen oder entfernen, da diese eine feste Größe haben.
Nand
@Nand nicht sicher, was ich dachte, aber beim Betrachten des Quellcodes erstellt die Arrays.asList-Methode tatsächlich eine ArrayList, die von dem angegebenen Array unterstützt wird. Vielen Dank für den Hinweis. Mein vorheriger Kommentar wurde gelöscht (konnte nicht bearbeitet werden).
Timmos
100
Hier ist eine funktionierende und effiziente Fisher-Yates-Shuffle-Array-Funktion:
privatestaticvoid shuffleArray(int[] array){int index;Random random =newRandom();for(int i = array.length -1; i >0; i--){
index = random.nextInt(i +1);if(index != i){
array[index]^= array[i];
array[i]^= array[index];
array[index]^= array[i];}}}
oder
privatestaticvoid shuffleArray(int[] array){int index, temp;Random random =newRandom();for(int i = array.length -1; i >0; i--){
index = random.nextInt(i +1);
temp = array[index];
array[index]= array[i];
array[i]= temp;}}
Abgestimmt, weil ich eine Lösung brauchte, die nicht den hohen Aufwand hatte, eine Sammlung von Ganzzahlen zu
erstellen
2
Hat die zweite Implementierung nicht das Potenzial, mit einem eigenen Index zu tauschen? random.nextInt(int bound)ist exklusiv, aber es i + 1als Argument zu geben, würde es erlauben indexund imöglicherweise dasselbe sein.
bmcentee148
21
@ bmcentee148 Das Austauschen eines Elements mit sich selbst ist in zufälliger Reihenfolge zulässig. Das Nichtverstehen schwächte das Rätsel und half Alan Turing, es zu knacken. en.wikipedia.org/wiki/…
Ellen Spertus
4
Der xorTrick ist großartig, um CPU-Register auszutauschen, wenn die CPU keinen Swap-Befehl hat und es keine freien Register gibt, aber für das Austauschen von Array-Elementen innerhalb einer Schleife sehe ich keinen Vorteil. Für die temporären lokalen Variablen gibt es keinen Grund, sie außerhalb der Schleife zu deklarieren.
Holger
1
Es ist etwas effizienter, die tempVariable außerhalb der Schleife zu deklarieren . Der XORTrick sollte schneller sein als die Verwendung einer tempVariablen, aber der einzige Weg, um sicherzugehen, dass ein Benchmark-Test durchgeführt wird.
Dan Bray
25
Die Collections- Klasse verfügt über eine effiziente Methode zum Mischen, die kopiert werden kann, um nicht davon abhängig zu sein:
/**
* Usage:
* int[] array = {1, 2, 3};
* Util.shuffle(array);
*/publicclassUtil{privatestaticRandom random;/**
* Code from method java.util.Collections.shuffle();
*/publicstaticvoid shuffle(int[] array){if(random ==null) random =newRandom();int count = array.length;for(int i = count; i >1; i--){
swap(array, i -1, random.nextInt(i));}}privatestaticvoid swap(int[] array,int i,int j){int temp = array[i];
array[i]= array[j];
array[j]= temp;}}
um nicht davon abhängig zu sein ? Ich würde mich viel lieber darauf verlassen, wenn das nur möglich wäre.
Shmosel
@shmosel Dann zögern Sie nicht, es zu benutzen. Stellen Sie sicher, dass Sie die erforderliche Klasse importieren und das Array in eine Liste mit konvertiert haben Arrays.asList. Sie müssen die resultierende Liste auch in ein Array konvertieren
KitKat
Sie können nicht Arrays.asList()für ein primitives Array verwenden. Und Sie müssten es nicht zurückkonvertieren, weil es nur ein Wrapper ist.
Shmosel
13
Schauen Sie sich Collectionsspeziell die Klasse an shuffle(...).
Wie benutzt man diese Sammlungsklasse in Android? Sie müssen einen speziellen Import durchführen (CRTL SHIFT O funktioniert nicht), um ihn zu verwenden?
Hubert
@ Hubert sollte es Teil des Pakets sein java.util. Es ist seit v1.2 Teil der Standardbibliothek.
MauganRa
3
Um Ihre Antwort eigenständiger zu gestalten, sollte sie Beispielcode enthalten. IE:import java.util.Collections; shuffle(solutionArray);
Stevoisiak
10
Hier ist eine Komplettlösung mit dem Collections.shuffleAnsatz:
publicstaticvoid shuffleArray(int[] array){List<Integer> list =newArrayList<>();for(int i : array){
list.add(i);}Collections.shuffle(list);for(int i =0; i < list.size(); i++){
array[i]= list.get(i);}}
Beachten Sie, dass es unter der Unfähigkeit von Java leidet, reibungslos zwischen int[]und Integer[](und damit int[]und List<Integer>) zu übersetzen.
Im Folgenden finden Sie drei verschiedene Implementierungen eines Shuffle. Sie sollten Collections.shuffle nur verwenden, wenn Sie mit einer Sammlung arbeiten. Sie müssen Ihr Array nicht in eine Sammlung einbinden, um es zu sortieren. Die folgenden Methoden sind sehr einfach zu implementieren.
Sie planen nicht die gleichen Dinge und Sie planen jedes nur einmal (dann zählt ihre Reihenfolge und Sie vergessen die Laufzeitoptimierung). Sie sollten und vor jedem Timing und einer Schleife aufrufen range, um etwas abschließen zu können (Pseudocode: mehrmals ausführen {Liste generieren, arr und iarr; Zeitmischungsliste; Zeitmixing arr; Zeitmixing iarr}). Meine Ergebnisse: 1.: . 100.: . Es zeigt nur, dass int [] voroptimiert ist (per Code), aber sie entsprechen fast der Laufzeitoptimierung. toArraytoPrimitivelist: 36017ns, arr: 28262ns, iarr: 23334nslist: 18445ns, arr: 19995ns, iarr: 18657ns
Syme
9
Die Verwendung ArrayList<Integer>kann Ihnen dabei helfen, das Problem des Mischens zu lösen, ohne viel Logik anzuwenden und weniger Zeit zu verbrauchen. Folgendes schlage ich vor:
ArrayList<Integer> x =newArrayList<Integer>();for(int i=1; i<=add.length(); i++){
x.add(i);}Collections.shuffle(x);
Dieser Code enthält nichts Java8-spezifisches. Dies funktioniert seit Java2. Nun, es würde funktionieren, wenn Sie die Inkonsistenz zwischen der ersten Verwendung listund dem plötzlichen Verweisen behoben haben cardsList. Da Sie jedoch das temporäre Element erstellen müssen list, das Sie weggelassen haben, hat der Collections.shuffle(Arrays.asList(arr));hier mehrmals gezeigte Ansatz keinen Vorteil . Welches funktioniert auch seit Java2.
Holger
3
Hier ist eine generische Version für Arrays:
import java.util.Random;publicclassShuffle<T>{privatefinalRandom rnd;publicShuffle(){
rnd =newRandom();}/**
* Fisher–Yates shuffle.
*/publicvoid shuffle(T[] ar){for(int i = ar.length -1; i >0; i--){int index = rnd.nextInt(i +1);
T a = ar[index];
ar[index]= ar[i];
ar[i]= a;}}}
Da ArrayList im Grunde genommen nur ein Array ist, kann es ratsam sein, mit einer ArrayList anstelle des expliziten Arrays zu arbeiten und Collections.shuffle () zu verwenden. Leistungstests zeigen jedoch keinen signifikanten Unterschied zwischen den oben genannten und Collections.sort ():
Shuffe<Integer>.shuffle(...) performance:576084 shuffles per second
Collections.shuffle(ArrayList<Integer>) performance:629400 shuffles per second
MathArrays.shuffle(int[]) performance:53062 shuffles per second
Die Apache Commons-Implementierung MathArrays.shuffle ist auf int [] beschränkt, und der Leistungsverlust ist wahrscheinlich auf den verwendeten Zufallszahlengenerator zurückzuführen.
Es sieht aus wie Sie passieren new JDKRandomGenerator()zu MathArrays.shuffle. Ich frage mich, wie sich das auf die Leistung auswirkt.
Brandon
Eigentlich ... sieht es so aus, als hätte MathArrays#shufflees eine Zuordnung in seiner Kernschleife : int targetIdx = new UniformIntegerDistribution(rng, start, i).sample();. Bizarr.
Brandon
3
Random rnd =newRandom();for(int i = ar.length -1; i >0; i--){int index = rnd.nextInt(i +1);// Simple swapint a = ar[index];
ar[index]= ar[i];
ar[i]= a;}
Übrigens ist mir aufgefallen, dass dieser Code eine ar.length - 1Reihe von Elementen zurückgibt. Wenn Ihr Array also 5 Elemente enthält, enthält das neue gemischte Array 4 Elemente. Dies geschieht, weil die for-Schleife sagt i>0. Wenn Sie zu wechseln i>=0, werden alle Elemente gemischt.
Nur einen Kopf hoch, möchten Sie dies möglicherweise in den Kommentarbereich Ihrer Frage verschieben, da diese wahrscheinlich markiert wird, wenn sie als eigene Antwort belassen wird.
Jason D
1
Dies scheint die Frage zu beantworten, daher bin ich mir nicht sicher, wovon Sie sprechen @JasonD
Sumurai8
1
Der Code ist korrekt, der Kommentar ist falsch. Wenn Sie ändern i>0zu i>=0, verschwenden Sie Zeit durch das Element Austausch 0mit sich.
jcsahnwaldt Reinstate Monica
3
Hier ist eine Lösung mit Apache Commons Math 3.x (nur für int [] Arrays):
Ich habe in einigen Antworten einige fehlende Informationen gesehen, also habe ich beschlossen, eine neue hinzuzufügen.
Java Sammlungen Arrays.asList nimmt var-arg vom Typ T (T ...). Wenn Sie ein primitives Array (int array) übergeben, leitet die asList-Methode ein ab und generiert einList<int[]> eine Liste mit einem Element ab (das eine Element ist das primitive Array). Wenn Sie diese Liste mit einem Element mischen, ändert dies nichts.
Zuerst müssen Sie Ihr primitives Array in ein Wrapper-Objektarray konvertieren. ArrayUtils.toObjectHierfür können Sie die Methode aus apache.commons.lang verwenden. Übergeben Sie dann das generierte Array an eine Liste und mischen Sie diese endgültig.
int[] intArr ={1,2,3};List<Integer> integerList =Arrays.asList(ArrayUtils.toObject(array));Collections.shuffle(integerList);//now! elements in integerList are shuffled!
Hier ist eine andere Möglichkeit, eine Liste zu mischen
publicList<Integer> shuffleArray(List<Integer> a){List<Integer> b =newArrayList<Integer>();while(a.size()!=0){int arrayIndex =(int)(Math.random()*(a.size()));
b.add(a.get(arrayIndex));
a.remove(a.get(arrayIndex));}return b;}
Wählen Sie eine Zufallszahl aus der Originalliste und speichern Sie sie in einer anderen Liste. Entfernen Sie dann die Nummer aus der Originalliste. Die Größe der Originalliste wird um eins verringert, bis alle Elemente in die neue Liste verschoben wurden.
Ich überlege mir diese sehr beliebte Frage, weil niemand eine Shuffle-Copy-Version geschrieben hat. Stil ist stark entlehnt Arrays.java, denn wer plündert heutzutage nicht die Java-Technologie? Generika und intImplementierungen enthalten.
/**
* Shuffles elements from {@code original} into a newly created array.
*
* @param original the original array
* @return the new, shuffled array
* @throws NullPointerException if {@code original == null}
*/@SuppressWarnings("unchecked")publicstatic<T> T[] shuffledCopy(T[] original){int originalLength = original.length;// For exception priority compatibility.Random random =newRandom();
T[] result =(T[])Array.newInstance(original.getClass().getComponentType(), originalLength);for(int i =0; i < originalLength; i++){int j = random.nextInt(i+1);
result[i]= result[j];
result[j]= original[i];}return result;}/**
* Shuffles elements from {@code original} into a newly created array.
*
* @param original the original array
* @return the new, shuffled array
* @throws NullPointerException if {@code original == null}
*/publicstaticint[] shuffledCopy(int[] original){int originalLength = original.length;Random random =newRandom();int[] result =newint[originalLength];for(int i =0; i < originalLength; i++){int j = random.nextInt(i+1);
result[i]= result[j];
result[j]= original[i];}return result;}
publicclassKnuth{// this class should not be instantiatedprivateKnuth(){}/**
* Rearranges an array of objects in uniformly random order
* (under the assumption that <tt>Math.random()</tt> generates independent
* and uniformly distributed numbers between 0 and 1).
* @param a the array to be shuffled
*/publicstaticvoid shuffle(Object[] a){int n = a.length;for(int i =0; i < n; i++){// choose index uniformly in [i, n-1]int r = i +(int)(Math.random()*(n - i));Object swap = a[r];
a[r]= a[i];
a[i]= swap;}}/**
* Reads in a sequence of strings from standard input, shuffles
* them, and prints out the results.
*/publicstaticvoid main(String[] args){// read in the dataString[] a =StdIn.readAllStrings();// shuffle the arrayKnuth.shuffle(a);// print results.for(int i =0; i < a.length; i++)StdOut.println(a[i]);}}
Die einfachste Lösung für dieses zufällige Mischen in einem Array.
String location[]={"delhi","banglore","mathura","lucknow","chandigarh","mumbai"};int index;String temp;Random random =newRandom();for(int i=1;i<location.length;i++){
index = random.nextInt(i+1);
temp = location[index];
location[index]= location[i];
location[i]= temp;System.out.println("Location Based On Random Values :"+location[i]);}
publicstaticvoid randomizeArray(int[] arr){Random rGenerator =newRandom();// Create an instance of the random class for(int i =0; i< arr.length;i++){//Swap the positions...int rPosition = rGenerator.nextInt(arr.length);// Generates an integer within the range (Any number from 0 - arr.length)int temp = arr[i];// variable temp saves the value of the current array index;
arr[i]= arr[rPosition];// array at the current position (i) get the value of the random generated
arr[rPosition]= temp;// the array at the position of random generated gets the value of temp}for(int i =0; i<arr.length; i++){System.out.print(arr[i]);//Prints out the array}}
Bitte fügen Sie eine verwandte Beschreibung zu Ihrer Antwort hinzu.
Ankit Suthar
0
import java.util.ArrayList;import java.util.Random;publicclass shuffle {publicstaticvoid main(String[] args){int a[]={1,2,3,4,5,6,7,8,9};ArrayList b =newArrayList();int i=0,q=0;Random rand =newRandom();while(a.length!=b.size()){int l = rand.nextInt(a.length);//this is one option to that but has a flaw on 0// if(a[l] !=0)// {// b.add(a[l]);// a[l]=0;// // }// // this works for every no. if(!(b.contains(a[l]))){
b.add(a[l]);}}// for (int j = 0; j <b.size(); j++) {// System.out.println(b.get(j));// // }System.out.println(b);}}
Random r =newRandom();int n = solutionArray.length;List<Integer> arr =Arrays.stream(solutionArray).boxed().collect(Collectors.toList());for(int i =0; i < n-1; i++){
solutionArray[i]= arr.remove( r.nextInt(arr.size()));// randomize base on size}
solutionArray[n-1]= arr.get(0);
Eine der Lösungen besteht darin, die Permutation zu verwenden, um alle Permutationen vorab zu berechnen und in der ArrayList zu speichern
Java 8 führte eine neue Methode, ints (), in die Klasse java.util.Random ein. Die Methode ints () gibt einen unbegrenzten Strom von pseudozufälligen int-Werten zurück. Sie können die Zufallszahlen zwischen einem bestimmten Bereich begrenzen, indem Sie den Minimal- und den Maximalwert angeben.
Random genRandom =newRandom();int num = genRandom.nextInt(arr.length);
Mit Hilfe der Generierung der Zufallszahl können Sie die Schleife durchlaufen und mit dem aktuellen Index gegen die Zufallszahl tauschen. Auf diese Weise können Sie eine Zufallszahl mit O (1) -Raumkomplexität generieren.
List<int[]>
einen Eintrag mit einem Eintrag erstellen . Siehe meine Antwort für den Weg, um dies mit zu erreichenCollections.shuffle()
.Antworten:
Die Verwendung von Sammlungen zum Mischen einer Reihe primitiver Typen ist ein wenig übertrieben ...
Es ist einfach genug, die Funktion selbst zu implementieren, indem Sie beispielsweise das Fisher-Yates-Shuffle verwenden :
quelle
println()
statt verwendenprintln("")
. Klarer in der Absicht denke ich :)Collections.shuffle(Arrays.asList(array))
funktioniert nicht, weil dieArrays.asList(array)
RückkehrCollection<int[]>
nicht so ist,Collection<Integer>
wie Sie gedacht haben.Hier ist ein einfacher Weg mit
ArrayList
:quelle
Collectons.shuffle(Arrays.asList(solutionArray));
Hier ist eine funktionierende und effiziente Fisher-Yates-Shuffle-Array-Funktion:
oder
quelle
random.nextInt(int bound)
ist exklusiv, aber esi + 1
als Argument zu geben, würde es erlaubenindex
undi
möglicherweise dasselbe sein.xor
Trick ist großartig, um CPU-Register auszutauschen, wenn die CPU keinen Swap-Befehl hat und es keine freien Register gibt, aber für das Austauschen von Array-Elementen innerhalb einer Schleife sehe ich keinen Vorteil. Für die temporären lokalen Variablen gibt es keinen Grund, sie außerhalb der Schleife zu deklarieren.temp
Variable außerhalb der Schleife zu deklarieren . DerXOR
Trick sollte schneller sein als die Verwendung einertemp
Variablen, aber der einzige Weg, um sicherzugehen, dass ein Benchmark-Test durchgeführt wird.Die Collections- Klasse verfügt über eine effiziente Methode zum Mischen, die kopiert werden kann, um nicht davon abhängig zu sein:
quelle
Arrays.asList
. Sie müssen die resultierende Liste auch in ein Array konvertierenArrays.asList()
für ein primitives Array verwenden. Und Sie müssten es nicht zurückkonvertieren, weil es nur ein Wrapper ist.Schauen Sie sich
Collections
speziell die Klasse anshuffle(...)
.quelle
java.util
. Es ist seit v1.2 Teil der Standardbibliothek.import java.util.Collections; shuffle(solutionArray);
Hier ist eine Komplettlösung mit dem
Collections.shuffle
Ansatz:Beachten Sie, dass es unter der Unfähigkeit von Java leidet, reibungslos zwischen
int[]
undInteger[]
(und damitint[]
undList<Integer>
) zu übersetzen.quelle
Sie haben hier ein paar Möglichkeiten. Eine Liste unterscheidet sich beim Mischen ein wenig von einem Array.
Wie Sie unten sehen können, ist ein Array schneller als eine Liste und ein primitives Array ist schneller als ein Objektarray.
Probendauer
Im Folgenden finden Sie drei verschiedene Implementierungen eines Shuffle. Sie sollten Collections.shuffle nur verwenden, wenn Sie mit einer Sammlung arbeiten. Sie müssen Ihr Array nicht in eine Sammlung einbinden, um es zu sortieren. Die folgenden Methoden sind sehr einfach zu implementieren.
ShuffleUtil-Klasse
Hauptmethode
Eine generische Liste mischen
Ein generisches Array mischen
Mischen eines primitiven Arrays
Dienstprogrammmethoden
Einfache Dienstprogrammmethoden zum Kopieren und Konvertieren von Arrays in Listen und umgekehrt.
Bereichsklasse
Erzeugt einen Wertebereich, ähnlich der Python-
range
Funktion.quelle
range
, um etwas abschließen zu können (Pseudocode: mehrmals ausführen {Liste generieren, arr und iarr; Zeitmischungsliste; Zeitmixing arr; Zeitmixing iarr}). Meine Ergebnisse: 1.: . 100.: . Es zeigt nur, dass int [] voroptimiert ist (per Code), aber sie entsprechen fast der Laufzeitoptimierung.toArray
toPrimitive
list: 36017ns, arr: 28262ns, iarr: 23334ns
list: 18445ns, arr: 19995ns, iarr: 18657ns
Die Verwendung
ArrayList<Integer>
kann Ihnen dabei helfen, das Problem des Mischens zu lösen, ohne viel Logik anzuwenden und weniger Zeit zu verbrauchen. Folgendes schlage ich vor:quelle
Der folgende Code erreicht eine zufällige Reihenfolge auf dem Array.
von: http://www.programcreek.com/2012/02/java-method-to-shuffle-an-int-array-with-random-order/
quelle
Sie können jetzt Java 8 verwenden:
quelle
list
und dem plötzlichen Verweisen behoben habencardsList
. Da Sie jedoch das temporäre Element erstellen müssenlist
, das Sie weggelassen haben, hat derCollections.shuffle(Arrays.asList(arr));
hier mehrmals gezeigte Ansatz keinen Vorteil . Welches funktioniert auch seit Java2.Hier ist eine generische Version für Arrays:
Da ArrayList im Grunde genommen nur ein Array ist, kann es ratsam sein, mit einer ArrayList anstelle des expliziten Arrays zu arbeiten und Collections.shuffle () zu verwenden. Leistungstests zeigen jedoch keinen signifikanten Unterschied zwischen den oben genannten und Collections.sort ():
Die Apache Commons-Implementierung MathArrays.shuffle ist auf int [] beschränkt, und der Leistungsverlust ist wahrscheinlich auf den verwendeten Zufallszahlengenerator zurückzuführen.
quelle
new JDKRandomGenerator()
zuMathArrays.shuffle
. Ich frage mich, wie sich das auf die Leistung auswirkt.MathArrays#shuffle
es eine Zuordnung in seiner Kernschleife :int targetIdx = new UniformIntegerDistribution(rng, start, i).sample();
. Bizarr.Übrigens ist mir aufgefallen, dass dieser Code eine
ar.length - 1
Reihe von Elementen zurückgibt. Wenn Ihr Array also 5 Elemente enthält, enthält das neue gemischte Array 4 Elemente. Dies geschieht, weil die for-Schleife sagti>0
. Wenn Sie zu wechselni>=0
, werden alle Elemente gemischt.quelle
i>0
zui>=0
, verschwenden Sie Zeit durch das Element Austausch0
mit sich.Hier ist eine Lösung mit Apache Commons Math 3.x (nur für int [] Arrays):
http://commons.apache.org/proper/commons-math/javadocs/api-3.6.1/org/apache/commons/math3/util/MathArrays.html#shuffle (int [])
Alternativ führte Apache Commons Lang 3.6 neue Shuffle-Methoden in die
ArrayUtils
Klasse ein (für Objekte und jeden primitiven Typ).http://commons.apache.org/proper/commons-lang/javadocs/api-release/org/apache/commons/lang3/ArrayUtils.html#shuffle-int:A-
quelle
Ich habe in einigen Antworten einige fehlende Informationen gesehen, also habe ich beschlossen, eine neue hinzuzufügen.
Java Sammlungen Arrays.asList nimmt var-arg vom Typ T
(T ...)
. Wenn Sie ein primitives Array (int array) übergeben, leitet die asList-Methode ein ab und generiert einList<int[]>
eine Liste mit einem Element ab (das eine Element ist das primitive Array). Wenn Sie diese Liste mit einem Element mischen, ändert dies nichts.Zuerst müssen Sie Ihr primitives Array in ein Wrapper-Objektarray konvertieren.
ArrayUtils.toObject
Hierfür können Sie die Methode aus apache.commons.lang verwenden. Übergeben Sie dann das generierte Array an eine Liste und mischen Sie diese endgültig.quelle
Hier ist eine andere Möglichkeit, eine Liste zu mischen
Wählen Sie eine Zufallszahl aus der Originalliste und speichern Sie sie in einer anderen Liste. Entfernen Sie dann die Nummer aus der Originalliste. Die Größe der Originalliste wird um eins verringert, bis alle Elemente in die neue Liste verschoben wurden.
quelle
Eine einfache Lösung für Groovy:
Dadurch werden alle Elemente der Array-Liste zufällig sortiert, wodurch das gewünschte Ergebnis des Mischens aller Elemente archiviert wird.
quelle
Mit Guaven ist
Ints.asList()
es so einfach wie:quelle
Ich überlege mir diese sehr beliebte Frage, weil niemand eine Shuffle-Copy-Version geschrieben hat. Stil ist stark entlehnt
Arrays.java
, denn wer plündert heutzutage nicht die Java-Technologie? Generika undint
Implementierungen enthalten.quelle
Dies ist der Knuth-Shuffle-Algorithmus.
quelle
Es gibt auch einen anderen Weg, noch nicht zu posten
auf diese Weise einfacher, abhängig vom Kontext
quelle
Die einfachste Lösung für dieses zufällige Mischen in einem Array.
quelle
int[]
bisInteger[]
Arrays.asList
Methode in eine ListeMit
Collections.shuffle
Methode mischenquelle
Einfachster zu mischender Code:
quelle
Verwenden der Zufallsklasse
quelle
quelle
quelle
ähnlich ohne Swap b
quelle
Eine der Lösungen besteht darin, die Permutation zu verwenden, um alle Permutationen vorab zu berechnen und in der ArrayList zu speichern
Java 8 führte eine neue Methode, ints (), in die Klasse java.util.Random ein. Die Methode ints () gibt einen unbegrenzten Strom von pseudozufälligen int-Werten zurück. Sie können die Zufallszahlen zwischen einem bestimmten Bereich begrenzen, indem Sie den Minimal- und den Maximalwert angeben.
Mit Hilfe der Generierung der Zufallszahl können Sie die Schleife durchlaufen und mit dem aktuellen Index gegen die Zufallszahl tauschen. Auf diese Weise können Sie eine Zufallszahl mit O (1) -Raumkomplexität generieren.
quelle
Ohne zufällige Lösung:
quelle