Java générant des nombres aléatoires non répétitifs

je veux créer un ensemble de nombres aléatoires sans doublons en Java.

par exemple, j'ai un tableau pour stocker 10.000 entiers aléatoires de 0 à 9999.

Voici ce que j'ai jusqu'à présent:

import java.util.Random;
public class Sort{

    public static void main(String[] args){

        int[] nums = new int[10000];

        Random randomGenerator = new Random();

        for (int i = 0; i < nums.length; ++i){
            nums[i] = randomGenerator.nextInt(10000);
        }
    }
}

Mais le code ci-dessus crée des doublons. Comment puis-je m'assurer que les nombres aléatoires ne se répètent pas?

25
demandé sur Eric Leschinski 2013-04-14 18:32:29

8 réponses

Integer[] arr = {...};
Collections.shuffle(Arrays.asList(arr));

Par exemple:

public static void main(String[] args) {
    Integer[] arr = new Integer[1000];
    for (int i = 0; i < arr.length; i++) {
        arr[i] = i;
    }
    Collections.shuffle(Arrays.asList(arr));
    System.out.println(Arrays.toString(arr));

}
37
répondu Achintya Jha 2013-04-14 14:42:56

un algorithme simple qui vous donne des nombres aléatoires sans duplicata peut être trouvé dans le livre Perles De Programmation p. 127.

Attention: Le tableau contient les nombres dans l'ordre! Si vous les voulez dans l'ordre aléatoire, vous devez mélanger le tableau, soit avec shuffle de Fisher–Yates ou en utilisant une Liste et appeler Collections.shuffle().

L'avantage de cet algorithme est que vous n'avez pas besoin de créer un tableau avec tous les les nombres possibles et la complexité de l'exécution est encore linéaireO(n).

public static int[] sampleRandomNumbersWithoutRepetition(int start, int end, int count) {
    Random rng = new Random();

    int[] result = new int[count];
    int cur = 0;
    int remaining = end - start;
    for (int i = start; i < end && count > 0; i++) {
        double probability = rng.nextDouble();
        if (probability < ((double) count) / (double) remaining) {
            count--;
            result[cur++] = i;
        }
        remaining--;
    }
    return result;
}
7
répondu the 2015-04-20 14:04:33

Achintya Jha a la bonne idée ici. Au lieu de penser à la façon de supprimer les doublons, vous supprimez la possibilité pour les doublons d'être créés en premier lieu.

Si vous voulez coller avec un tableau d'entiers et voulez leur ordre aléatoire (manuellement, ce qui est assez simple) de suivre ces étapes.

  1. créer un tableau de taille n.
  2. parcourir et d'initialiser chaque valeur à l'indice i la valeur i (ou i+1 si vous souhaitez avoir les chiffres de 1 à n plutôt que de 0 à n-1).
  3. enfin, bouclez la boucle à travers le tableau en changeant de nouveau chaque valeur pour une valeur à un index aléatoire.

Votre code pourrait être modifié pour ressembler à ceci:

import java.util.Random;

public class Sort
{
    // use a constant rather than having the "magic number" 10000 scattered about
    public static final int N = 10000;

    public static void main(String[] args)
    {
        //array to store N random integers (0 - N-1)
        int[] nums = new int[N];

        // initialize each value at index i to the value i 
        for (int i = 0; i < nums.length; ++i)
        {
            nums[i] = i;
        }

        Random randomGenerator = new Random();
        int randomIndex; // the randomly selected index each time through the loop
        int randomValue; // the value at nums[randomIndex] each time through the loop

        // randomize order of values
        for(int i = 0; i < nums.length; ++i)
        {
             // select a random index
             randomIndex = randomGenerator.nextInt(nums.length);

             // swap values
             randomValue = nums[randomIndex];
             nums[randomIndex] = nums[i];
             nums[i] = randomValue;
        }
    }
}

et si j'étais vous, je casserais probablement chacun de ces blocs en méthodes séparées, plus petites plutôt que d'avoir une grande méthode principale.

Espérons que cette aide.

3
répondu Benjamin Brumfield 2013-05-20 18:35:40

Si vous avez besoin de générer des nombres avec les intervalles, il peut être juste comme ça:

Integer[] arr = new Integer[((int) (Math.random() * (16 - 30) + 30))];
for (int i = 0; i < arr.length; i++) {
arr[i] = i;
}
Collections.shuffle(Arrays.asList(arr));
System.out.println(Arrays.toString(arr));`

Le résultat:

[1, 10, 2, 4, 9, 8, 7, 13, 18, 17, 5, 21, 12, 16, 23, 20, 6, 0, 22, 14, 24, 15, 3, 11, 19]

Remarque:

Si vous avez besoin que le zéro ne vous laisse pas pu mettre un "si"

2
répondu Marcus person 2017-11-08 07:26:59

Comment à ce sujet?

LinkedHashSet<Integer> test = new LinkedHashSet<Integer>();
Random random = new Random();
do{
    test.add(random.nextInt(1000) + 1);
}while(test.size() != 1000);

L'utilisateur peut alors parcourir le Set utilisation d'un pour boucle.

1
répondu Jitin Kodian 2016-04-28 09:48:46

En Java 8, si vous voulez avoir un list de non-répétition N nombres entiers aléatoires en range (a, b), où b est exclusive, vous pouvez utiliser quelque chose comme ceci:

Random random = new Random();
List<Integer> randomNumbers = random.ints(a, b).distinct().limit(N).boxed().collect(Collectors.toList());
1
répondu Slawomir Domagala 2018-04-26 06:38:07
public class Randoms {

static int z, a = 1111, b = 9999, r;

public static void main(String ... args[])
{
       rand();
}

    public static void rand() {

    Random ran = new Random();
    for (int i = 1; i == 1; i++) {
        z = ran.nextInt(b - a + 1) + a;
        System.out.println(z);
        randcheck();
    }
}

private static void randcheck() {

    for (int i = 3; i >= 0; i--) {
        if (z != 0) {
            r = z % 10;
            arr[i] = r;
            z = z / 10;
        }
    }
    for (int i = 0; i <= 3; i++) {
        for (int j = i + 1; j <= 3; j++) {
            if (arr[i] == arr[j]) {
                rand();
            }
        }

    }
}
}
0
répondu jayanthanantharapu 2014-07-11 07:24:21
HashSet<Integer>hashSet=new HashSet<>();
Random random = new Random();
//now add random number to this set
while(true)
{
    hashSet.add(random.nextInt(1000));
    if(hashSet.size()==1000)
        break;
}
0
répondu Vaibhav Jain 2018-09-20 10:38:38