Aléatoire d'un tableau de brassage
J'ai besoin de façon aléatoire lecture aléatoire du Tableau ci-après:
int[] solutionArray = {1, 2, 3, 4, 5, 6, 6, 5, 4, 3, 2, 1};
Est-il une fonction pour faire cela?
- C'est la méthode SDK vous êtes à la recherche pour les Collections.shuffle(Tableaux.asList(array));
- Non, cela ne fonctionne pas. Créer un
List<int[]>
contenant une entrée. Voir ma réponse pour la façon de le réaliser à l'aide deCollections.shuffle()
. - Pas vraiment une réponse à la question d'origine, mais MathArrays.shuffle de la chambre des communes-math3 bibliothèque fait le travail.
- Ce n'est pas le sujet assez pour justifier une réponse, mais je me souviens vraiment un super article de "Graphiques Gemmes" livre qui parle de la traversée d'un tableau de pseudo ordre aléatoire. Dans mon esprit que les battements d'avoir à mélanger les données en premier lieu. Le C-la mise en œuvre se trouve ici github.com/erich666/GraphicsGems/blob/master/gems/Dissolve.c
- Voir aussi cette étroitement liés à la question: stackoverflow.com/questions/2450954/...
Vous devez vous connecter pour publier un commentaire.
À l'aide de Collections de mélanger un tableau de types primitifs est un peu exagéré...
Il est assez simple à mettre en œuvre la fonction de vous-même, en utilisant par exemple la Shuffle de Fisher–Yates:
println()
au lieu deprintln("")
. Plus clair, dans l'intention, je pense 🙂(i + 1)
ne fonctionne pas parce que je suis en utilisant le XOR méthode pour permuter les variables et lorsque les variables sont les mêmes, les deux variables sont mis à 0. Je vais mettre à jour le code que j'ai posté.Arrays.asList(array)
retourneCollection<int[]>
pasCollection<Integer>
que vous le pensiez.Collections.shuffle
overkill?Arrays.asList(array)
ne retourne pasCollection<int[]>
il retourneint[]
primitives ne peuvent pas être de type générique.println
Random
au lieu deThreadLocalRandom
ou est-ce seulement une question de surcharge/ performance?new Random()
avant... je pense que le but est d'être en sécurité dans le cas où le code est utilisé par plusieurs threads, qu'ils ne sont pas d'attendre la disponibilité de la global Aléatoire dans les virages. Je n'ai pas cela, il y a une différence avec un seul thread, mais il ressemble toujours a l'option sécuritaire.Ici est une façon simple à l'aide d'un
ArrayList
:List<Integer>
àArrayList<Integer>
. Toujours le code de l'interface; l'original est beaucoup mieux que ce que vous êtes en train de suggérer. Aussi les importations sont à leur place dans ce fragment de code.Ici est un travail efficace et de Fisher–Yates shuffle fonction de tableau:
ou
random.nextInt(int bound)
est exclusif, mais en lui donnanti + 1
comme un argument permettraitindex
eti
pour éventuellement être le même.xor
truc est idéal pour échanger des registres du CPU lorsque le CPU n'a pas de swap d'instruction et il n'y a pas de libre registres, mais aussi pour échanger des éléments d'un tableau à l'intérieur d'une boucle, je ne vois pas l'avantage. Pour les locaux temporaires de variables, il n'y a pas de raison de les déclarer en dehors de la boucle.temp
variable en dehors de la boucle. LeXOR
truc devrait être plus rapide que d'utiliser untemp
variable, mais la seule façon d'en être sûr pour effectuer un test de référence.static <V> void shuffle(V[] array, Random random)
Collections classe a une méthode efficace pour traînant, qui peut être copié, afin de ne pas en dépendre:
Arrays.asList
. Vous devez convertir la liste à un tableau, tropArrays.asList()
sur une primitive de tableau. Vous n'avez pas besoin de convertir en arrière, car il est juste un wrapper.Regarder la
Collections
classe, plus précisémentshuffle(...)
.java.util
. Il fait partie de la bibliothèque standard depuis v1.2.import java.util.Collections; shuffle(solutionArray);
Ici est une solution complète à l'aide de la
Collections.shuffle
approche:Noter qu'il souffre à cause de Java à l'incapacité de la douceur, de traduire entre
int[]
etInteger[]
(et doncint[]
etList<Integer>
).Vous avez deux options ici. Une liste est un peu différente de celle d'un tableau quand il s'agit de brassage.
Comme vous pouvez le voir ci-dessous, un tableau est plus rapide qu'une liste, et une primitive de la matrice est plus rapide qu'un tableau d'objets.
Échantillon Durées
Ci-dessous, sont trois implémentations différentes d'un shuffle. Vous devez utiliser uniquement des Collections.shuffle si vous avez affaire à une collection. Il n'est pas nécessaire d'envelopper votre tableau dans une collection juste pour faire le tri. Les méthodes ci-dessous sont très simples à mettre en œuvre.
ShuffleUtil Classe
Principale Méthode
Traînant une Liste Générique
Aléatoire d'un Générique de la Matrice de
Aléatoire d'un Primitif Tableau
Les Méthodes De L'Utilitaire
Simple les méthodes de l'utilitaire pour copier et convertir les tableaux de listes et vice-versa.
Gamme Classe
Génère une plage de valeurs, semblable à Python
range
fonction.range
,toArray
ettoPrimitive
avant tout de timing et de la boucle pour être en mesure de conclure quoi que ce soit (pseudo-code: faire plusieurs fois { générer la liste, arr et iarr; le temps de brassage de la liste; le temps de brassage arr; temps de brassage iarr }). Mes résultats: 1er:list: 36017ns, arr: 28262ns, iarr: 23334ns
. 100ème:list: 18445ns, arr: 19995ns, iarr: 18657ns
. Il montre simplement int[] est pré-optimisé (par code), mais ils sont presque équivalent à l'exécution de l'optimisation.À l'aide de
ArrayList<Integer>
peut vous aider à résoudre le problème de brassage sans appliquer de beaucoup de logique et de consommer moins de temps. Voici ce que je propose:Le code suivant sera d'atteindre un hasard de la commande sur le tableau.
à partir de: http://www.programcreek.com/2012/02/java-method-to-shuffle-an-int-array-with-random-order/
Vous pouvez utiliser java 8:
list
et, soudain, se référant àcardsList
. Mais puisque vous avez besoin pour créer le temporairelist
, que vous avez omis, il n'y a aucun avantage sur leCollections.shuffle(Arrays.asList(arr));
approche montré à plusieurs reprises ici. Qui travaille également depuis Java2.Ici est un des Génériques de la version pour les tableaux:
Considérant que ArrayList est fondamentalement juste un tableau, il peut être conseillé de travailler avec une liste de tableaux à la place de l'explicite tableau et utiliser les Collections.shuffle(). Tests de Performance, cependant, ne montrent aucune différence significative entre les ci-dessus et des Collections.sort():
Apache Commons mise en œuvre MathArrays.shuffle est limitée à int[] et la dégradation des performances est probablement dû au générateur de nombre aléatoire utilisé.
new JDKRandomGenerator()
àMathArrays.shuffle
. Je me demande comment cela affecte les performances?MathArrays#shuffle
a une allocation dans son cœur de boucle:int targetIdx = new UniformIntegerDistribution(rng, start, i).sample();
. Bizarre.Par ailleurs, j'ai remarqué que ce code renvoie une
ar.length - 1
nombre d'éléments, donc, si votre tableau comporte 5 éléments, le nouveau mélangées tableau de 4 éléments. Cela se produit parce que la boucle for diti>0
. Si vous changez dei>=0
, vous obtenez tous les éléments dans un ordre aléatoire.i>0
ài>=0
, vous perdez du temps en échangeant élément0
avec lui-même.Voici une solution à l'aide d'Apache Commons Mathématiques 3.x (int[] tableaux):
http://commons.apache.org/proper/commons-math/javadocs/api-3.6.1/org/apache/commons/math3/util/MathArrays.html#shuffle(int%5B%5D)
Sinon, Apache Commons Lang 3.6 introduit de nouveaux shuffle méthodes pour la
ArrayUtils
classe (pour les objets et tout type primitif).http://commons.apache.org/proper/commons-lang/javadocs/api-release/org/apache/commons/lang3/ArrayUtils.html#shuffle-int:A-
J'ai vu un certain manque d'informations dans certaines réponses, j'ai donc décidé d'en ajouter une nouvelle.
Java collections de Tableaux.asList prend var-arg de type T
(T ...)
. Si vous passez une primitive de tableau (tableau int), asList méthode de déduire et de générer unList<int[]>
, qui est un élément de la liste (l'un des éléments est la primitive de tableau). si vous shuffle un seul élément de la liste, cela ne va pas changer quelque chose.Donc, vous devez d'abord les convertir vous primitive tableau de Wrapper tableau d'objets. pour cela, vous pouvez utiliser
ArrayUtils.toObject
méthode de apache.commons.lang. passer ensuite le générés tableau à une Liste et finalement shuffle qui.Voici une autre façon de mélanger une liste
Choisir un nombre aléatoire à partir de la liste d'origine et de l'enregistrer dans une autre liste.Ensuite, retirez le numéro de la liste d'origine.La taille de la liste d'origine seront continuez à diminuer par un jusqu'à ce que tous les éléments sont déplacés vers la nouvelle liste.
Une solution simple pour Groovy:
Cela permettra de trier tous les éléments de la liste de tableau au hasard des archives qui le résultat souhaité de mélanger tous les éléments.
int[]
àInteger[]
Arrays.asList
méthodeShuffle avec
Collections.shuffle
méthodeJe me suis pesée ce très populaire en question, parce que personne n'a écrit un shuffle-version de la copie. Le Style est emprunté de
Arrays.java
, car qui n'est pas pillage de la technologie Java, ces jours-ci? Générique etint
implémentations inclus.C'est knuth algorithme de shuffle.
Il y a une autre façon, pas encore
de cette façon plus facile, dépendait du contexte
La solution la plus simple pour ce Aléatoires Traînant dans un Tableau.
Plus simple code à lecture aléatoire:
similaire, sans l'aide de swap b
L'une des solution est d'utiliser la permutation de pré-calculer toutes les permutations et stockées dans la liste de tableaux
Java 8 introduit une nouvelle méthode, ints(), java.util.Hasard de classe. Les services de renseignements() la méthode renvoie un nombre illimité de flux de pseudo valeurs int. Vous pouvez limiter le nombres aléatoires entre une plage spécifiée en fournissant le minimum et le maximum des valeurs.
Avec l'aide de la génération du nombre aléatoire, Vous pouvez parcourir la boucle et échanger avec l'index en cours avec le nombre aléatoire..
C'est la façon dont vous pouvez générer un nombre aléatoire avec O(1) l'espace de la complexité.
À l'aide de la Goyave est
Ints.asList()
c'est aussi simple que: