J'essaie d'obtenir des nombres aléatoires entre 0 et 100. Mais je veux qu'ils soient uniques et non répétés dans une séquence. Par exemple, si j'ai 5 nombres, ils devraient être 82,12,53,64,32 et non 82,12,53,12,32 J'ai utilisé ceci, mais cela génère les mêmes nombres dans une séquence.
Random rand = new Random();
selected = rand.nextInt(100);
1..100
(il existe des algorithmes célèbres pour cela), mais arrêtez-vous après avoir déterminé les premiersn
éléments.Réponses:
Voici une implémentation simple. Cela imprimera 3 nombres aléatoires uniques de la gamme 1-10.
import java.util.ArrayList; import java.util.Collections; public class UniqueRandomNumbers { public static void main(String[] args) { ArrayList<Integer> list = new ArrayList<Integer>(); for (int i=1; i<11; i++) { list.add(new Integer(i)); } Collections.shuffle(list); for (int i=0; i<3; i++) { System.out.println(list.get(i)); } } }
La première partie du correctif avec l'approche d'origine, comme Mark Byers l'a souligné dans une réponse maintenant supprimée, consiste à n'utiliser qu'une seule
Random
instance.C'est ce qui fait que les chiffres sont identiques. Une
Random
instance est prédéfinie par l'heure actuelle en millisecondes. Pour une valeur de départ particulière , l'instance «aléatoire» renverra exactement la même séquence de nombres pseudo aléatoires .La première boucle for peut simplement être changée en:
for (int i = 1; i < 11; i++) { list.add(i); }
la source
Avec Java 8+, vous pouvez utiliser la
ints
méthode deRandom
pour obtenirIntStream
ensuite des valeurs aléatoiresdistinct
etlimit
réduire le flux à un certain nombre de valeurs aléatoires uniques.ThreadLocalRandom.current().ints(0, 100).distinct().limit(5).forEach(System.out::println);
Random
a également des méthodes qui créent desLongStream
s et desDoubleStream
s si vous en avez besoin à la place.Si vous voulez que tous (ou une grande quantité) des nombres dans une plage dans un ordre aléatoire, il peut être plus efficace d'ajouter tous les nombres à une liste, de la mélanger et de prendre le premier n car l'exemple ci-dessus est actuellement implémenté en générant des nombres aléatoires dans la plage demandée et en les passant à travers un ensemble (similaire à la réponse de Rob Kielty ), ce qui peut nécessiter de générer beaucoup plus que le montant passé à la limite car la probabilité de générer un nouveau nombre unique diminue avec chacun trouvé. Voici un exemple de l'autre manière:
List<Integer> range = IntStream.range(0, 100).boxed() .collect(Collectors.toCollection(ArrayList::new)); Collections.shuffle(range); range.subList(0, 99).forEach(System.out::println);
la source
Arrays#setAll()
c'est un peu plus rapide qu'un flux. Donc: `Integer [] indices = new Integer [n]; Arrays.setAll (indices, i -> i); Collections.shuffle (Arrays.asList (indices)); return Arrays.stream (indices) .mapToInt (Integer :: intValue) .toArray (); `long
où vous déplacez et masquez pour accéder à des bits individuels.)la source
pick()
est un exemple.HashSet
, où vous stockez les nombres que vous avez déjà générés et utilisezcontains
pour tester si vous avez déjà généré ce nombre. LeHashSet
sera probablement légèrement plus lent qu'un tableau booléen, mais prendra moins de mémoire.Utilisez
Collections.shuffle()
sur les 100 numéros et sélectionnez les cinq premiers, comme indiqué ici .la source
Je pense que cette méthode mérite d'être mentionnée.
private static final Random RANDOM = new Random(); /** * Pick n numbers between 0 (inclusive) and k (inclusive) * While there are very deterministic ways to do this, * for large k and small n, this could be easier than creating * an large array and sorting, i.e. k = 10,000 */ public Set<Integer> pickRandom(int n, int k) { final Set<Integer> picked = new HashSet<>(); while (picked.size() < n) { picked.add(RANDOM.nextInt(k + 1)); } return picked; }
la source
J'ai retravaillé la réponse d'Anand pour utiliser non seulement les propriétés uniques d'un ensemble, mais aussi utiliser le booléen false renvoyé par le
set.add()
lorsqu'un ajout à l'ensemble échoue.import java.util.HashSet; import java.util.Random; import java.util.Set; public class randomUniqueNumberGenerator { public static final int SET_SIZE_REQUIRED = 10; public static final int NUMBER_RANGE = 100; public static void main(String[] args) { Random random = new Random(); Set set = new HashSet<Integer>(SET_SIZE_REQUIRED); while(set.size()< SET_SIZE_REQUIRED) { while (set.add(random.nextInt(NUMBER_RANGE)) != true) ; } assert set.size() == SET_SIZE_REQUIRED; System.out.println(set); } }
la source
SET_SIZE_REQUIRED
est assez grand (disons, plusNUMBER_RANGE / 2
J'ai fait ça comme ça.
Random random = new Random(); ArrayList<Integer> arrayList = new ArrayList<Integer>(); while (arrayList.size() < 6) { // how many numbers u need - it will 6 int a = random.nextInt(49)+1; // this will give numbers between 1 and 50. if (!arrayList.contains(a)) { arrayList.add(a); } }
la source
Cela fonctionnera pour générer des nombres aléatoires uniques ................
import java.util.HashSet; import java.util.Random; public class RandomExample { public static void main(String[] args) { Random rand = new Random(); int e; int i; int g = 10; HashSet<Integer> randomNumbers = new HashSet<Integer>(); for (i = 0; i < g; i++) { e = rand.nextInt(20); randomNumbers.add(e); if (randomNumbers.size() <= 10) { if (randomNumbers.size() == 10) { g = 10; } g++; randomNumbers.add(e); } } System.out.println("Ten Unique random numbers from 1 to 20 are : " + randomNumbers); } }
la source
Une manière intelligente de faire ceci est d'utiliser les exposants d'un élément primitif dans le module.
Par exemple, 2 est un mod racine primitif 101, ce qui signifie que les puissances de 2 mod 101 vous donnent une séquence non répétitive qui voit chaque nombre de 1 à 100 inclus:
2^0 mod 101 = 1 2^1 mod 101 = 2 2^2 mod 101 = 4 ... 2^50 mod 101 = 100 2^51 mod 101 = 99 2^52 mod 101 = 97 ... 2^100 mod 101 = 1
Dans le code Java, vous écririez:
void randInts() { int num=1; for (int ii=0; ii<101; ii++) { System.out.println(num); num= (num*2) % 101; } }
Trouver une racine primitive pour un module spécifique peut être délicat, mais la fonction "primroot" de Maple le fera pour vous.
la source
Je suis venu ici d'une autre question, qui a été dupliquée de cette question ( Générer un nombre aléatoire unique en java )
Stockez de 1 à 100 numéros dans un tableau.
Génère un nombre aléatoire entre 1 et 100 comme position et renvoie le tableau [position-1] pour obtenir la valeur
Une fois que vous utilisez un nombre dans le tableau, marquez la valeur comme -1 (pas besoin de maintenir un autre tableau pour vérifier si ce nombre est déjà utilisé)
Si la valeur du tableau est -1, récupérez à nouveau le nombre aléatoire pour récupérer le nouvel emplacement du tableau.
la source
J'ai une solution facile à ce problème, avec cela, nous pouvons facilement générer un nombre n de nombres aléatoires uniques, c'est juste logique que tout le monde peut l'utiliser dans n'importe quelle langue.
for(int i=0;i<4;i++) { rn[i]= GenerateRandomNumber(); for (int j=0;j<i;j++) { if (rn[i] == rn[j]) { i--; } } }
la source
break;
après lei—;
essayez ça
public class RandomValueGenerator { /** * */ private volatile List<Double> previousGenValues = new ArrayList<Double>(); public void init() { previousGenValues.add(Double.valueOf(0)); } public String getNextValue() { Random random = new Random(); double nextValue=0; while(previousGenValues.contains(Double.valueOf(nextValue))) { nextValue = random.nextDouble(); } previousGenValues.add(Double.valueOf(nextValue)); return String.valueOf(nextValue); } }
la source
Ce n'est pas très différent des autres réponses, mais je voulais le tableau d'entiers à la fin:
Integer[] indices = new Integer[n]; Arrays.setAll(indices, i -> i); Collections.shuffle(Arrays.asList(indices)); return Arrays.stream(indices).mapToInt(Integer::intValue).toArray();
la source
vous pouvez utiliser un tableau booléen pour remplir la valeur true si la valeur prise sinon définie naviguer dans le tableau booléen pour obtenir la valeur comme indiqué ci-dessous
package study; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /* Created By Sachin Rane on Jul 18, 2018 */ public class UniqueRandomNumber { static Boolean[] boolArray; public static void main(String s[]){ List<Integer> integers = new ArrayList<>(); for (int i = 0; i < 10; i++) { integers.add(i); } //get unique random numbers boolArray = new Boolean[integers.size()+1]; Arrays.fill(boolArray, false); for (int i = 0; i < 10; i++) { System.out.print(getUniqueRandomNumber(integers) + " "); } } private static int getUniqueRandomNumber(List<Integer> integers) { int randNum =(int) (Math.random()*integers.size()); if(boolArray[randNum]){ while(boolArray[randNum]){ randNum++; if(randNum>boolArray.length){ randNum=0; } } boolArray[randNum]=true; return randNum; }else { boolArray[randNum]=true; return randNum; } } }
la source
Choisissez n nombres aléatoires uniques de 0 à m-1.
int[] uniqueRand(int n, int m){ Random rand = new Random(); int[] r = new int[n]; int[] result = new int[n]; for(int i = 0; i < n; i++){ r[i] = rand.nextInt(m-i); result[i] = r[i]; for(int j = i-1; j >= 0; j--){ if(result[i] >= r[j]) result[i]++; } } return result; }
Imaginez une liste contenant des nombres de 0 à m-1. Pour choisir le premier nombre, nous utilisons simplement
rand.nextInt(m)
. Supprimez ensuite le numéro de la liste. Maintenant, il reste des numéros m-1, alors nous appelonsrand.nextInt(m-1)
. Le nombre que nous obtenons représente la position dans la liste. S'il est inférieur au premier nombre, alors c'est le deuxième nombre, puisque la partie de la liste précédant le premier nombre n'a pas été modifiée par la suppression du premier nombre. Si la position est supérieure ou égale au premier nombre, le deuxième nombre est la position + 1. Faites une dérivation supplémentaire, vous pouvez obtenir cet algorithme.Explication
Cet algorithme a une complexité O (n ^ 2). Il est donc utile de générer une petite quantité de nombres uniques à partir d'un grand ensemble. Alors que l'algorithme basé sur le shuffle a besoin d'au moins O (m) pour effectuer le shuffle.
L'algorithme basé sur le shuffle a également besoin de mémoire pour stocker tous les résultats possibles pour effectuer le shuffle, cet algorithme n'en a pas besoin.
la source
Vous pouvez utiliser la classe Collections.
Une classe utilitaire appelée Collections propose différentes actions qui peuvent être effectuées sur une collection comme une ArrayList (par exemple, rechercher les éléments, trouver l'élément maximum ou minimum, inverser l'ordre des éléments, etc.). L'une des actions qu'il peut effectuer est de mélanger les éléments. La lecture aléatoire déplacera chaque élément de manière aléatoire vers une position différente dans la liste. Il le fait en utilisant un objet Random. Cela signifie que c'est un hasard déterministe, mais cela fonctionnera dans la plupart des situations.
Pour mélanger ArrayList, ajoutez l'importation de collections en haut du programme, puis utilisez la méthode statique Shuffle. Il faut que ArrayList soit mélangé en tant que paramètre:
import java.util.Collections; import java.util.ArrayList; public class Lottery { public static void main(String[] args) { //define ArrayList to hold Integer objects ArrayList numbers = new ArrayList(); for(int i = 0; i < 100; i++) { numbers.add(i+1); } Collections.shuffle(numbers); System.out.println(numbers); } }
la source
Bien que ce soit un vieux fil, mais l'ajout d'une autre option pourrait ne pas nuire. (Les fonctions lambda du JDK 1.8 semblent faciliter les choses);
Le problème peut être décomposé selon les étapes suivantes;
Voici la fonction avec une description:
/** * Provided an unsequenced / sequenced list of integers, the function returns unique random IDs as defined by the parameter * @param numberToGenerate * @param idList * @return List of unique random integer values from the provided list */ private List<Integer> getUniqueRandomInts(List<Integer> idList, Integer numberToGenerate) { List<Integer> generatedUniqueIds = new ArrayList<>(); Integer minId = idList.stream().mapToInt (v->v).min().orElseThrow(NoSuchElementException::new); Integer maxId = idList.stream().mapToInt (v->v).max().orElseThrow(NoSuchElementException::new); ThreadLocalRandom.current().ints(minId,maxId) .filter(e->idList.contains(e)) .distinct() .limit(numberToGenerate) .forEach(generatedUniqueIds:: add); return generatedUniqueIds; }
Ainsi, pour obtenir 11 nombres aléatoires uniques pour l'objet de liste 'allIntegers', nous appellerons la fonction comme;
List<Integer> ids = getUniqueRandomInts(allIntegers,11);
La fonction déclare le nouveau arrayList 'generatedUniqueIds' et remplit chaque entier aléatoire unique jusqu'au nombre requis avant de retourner.
La classe PS ThreadLocalRandom évite la valeur de départ commune en cas de threads simultanés.
la source
Il s'agit de la méthode la plus simple pour générer des valeurs aléatoires uniques dans une plage ou à partir d'un tableau .
Dans cet exemple, j'utiliserai un tableau prédéfini, mais vous pouvez également adapter cette méthode pour générer des nombres aléatoires. Tout d'abord, nous allons créer un exemple de tableau à partir duquel récupérer nos données.
ArrayList<Integer> sampleList = new ArrayList<>(); sampleList.add(1); sampleList.add(2); sampleList.add(3); sampleList.add(4); sampleList.add(5); sampleList.add(6); sampleList.add(7); sampleList.add(8);
Maintenant, à partir du,
sampleList
nous allons produire cinq nombres aléatoires uniques.int n; randomList = new ArrayList<>(); for(int i=0;i<5;i++){ Random random = new Random(); n=random.nextInt(8); //Generate a random index between 0-7 if(!randomList.contains(sampleList.get(n))) randomList.add(sampleList.get(n)); else i--; //reiterating the step }
C'est conceptuellement très simple. Si la valeur aléatoire générée existe déjà, nous réitérerons l'étape. Cela continuera jusqu'à ce que toutes les valeurs générées soient uniques.
Si vous avez trouvé cette réponse utile, vous pouvez la voter car son concept est beaucoup plus simple que les autres réponses .
la source
Vous pouvez générer n nombre aléatoire unique entre 0 et n-1 en java
public static void RandomGenerate(int n) { Set<Integer> st=new HashSet<Integer>(); Random r=new Random(); while(st.size()<n) { st.add(r.nextInt(n)); }
}
la source
Vérifie ça
public class RandomNumbers { public static void main(String[] args) { // TODO Auto-generated method stub int n = 5; int A[] = uniqueRandomArray(n); for(int i = 0; i<n; i++){ System.out.println(A[i]); } } public static int[] uniqueRandomArray(int n){ int [] A = new int[n]; for(int i = 0; i< A.length; ){ if(i == A.length){ break; } int b = (int)(Math.random() *n) + 1; if(f(A,b) == false){ A[i++] = b; } } return A; } public static boolean f(int[] A, int n){ for(int i=0; i<A.length; i++){ if(A[i] == n){ return true; } } return false; } }
la source
Voici une façon dont j'avais l'habitude de générer toujours un numéro unique. La fonction aléatoire génère un nombre et le stocke dans un fichier texte, puis la prochaine fois qu'elle le vérifie dans le fichier, le compare et génère un nouveau numéro unique, de sorte qu'il y a toujours un nouveau numéro unique.
public int GenerateRandomNo() { int _min = 0000; int _max = 9999; Random _rdm = new Random(); return _rdm.Next(_min, _max); } public int rand_num() { randnum = GenerateRandomNo(); string createText = randnum.ToString() + Environment.NewLine; string file_path = System.IO.Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath) + @"\Invoices\numbers.txt"; File.AppendAllText(file_path, createText); int number = File.ReadLines(file_path).Count(); //count number of lines in file System.IO.StreamReader file = new System.IO.StreamReader(file_path); do { randnum = GenerateRandomNo(); } while ((file.ReadLine()) == randnum.ToString()); file.Close(); return randnum; }
la source