8 votes

Quelle est la meilleure façon d'obtenir quatre numéros aléatoires uniques de 0 à 9 ?

Je veux générer quatre nombres aléatoires dans la gamme de 0 à 9. Il est facile de générer quatre nombres aléatoires avec la classe Java Random.

    Random random = new Random();

    int numbers[] = new int[4];

    for(int i=0;i<4;i++){

        numbers[i] = random.nextInt(10);

    }

Avec cela, je peux obtenir un tableau de quatre nombres facilement comme, 9369 , 4702 etc. Dans ce cas, il est possible qu'un nombre soit répété dans quatre nombres et je ne veux pas de telles répétitions dans les nombres.

Ici, je veux que les quatre chiffres du tableau ci-dessus soient uniques afin que je puisse obtenir un résultat tel que 9543 , 1234 etc.

Pour cela, j'ai réfléchi de la manière suivante.

  1. Générer un numéro aléatoire et l'attribuer comme premier numéro.
  2. Générez un numéro aléatoire et vérifiez si le premier numéro est différent du second, sinon générez à nouveau un numéro aléatoire et répétez l'opération, et ainsi de suite.

Existe-t-il un meilleur moyen que la méthode ci-dessus pour obtenir quatre numéros aléatoires uniques facilement et rapidement ?

Toute suggestion est la bienvenue.

32voto

Eran Points 35360

Vous pouvez utiliser Collections.shuffle :

// generate a List that contains the numbers 0 to 9
List<Integer> digits = IntStream.range(0,10).boxed().collect(Collectors.toList());
// shuffle the List
Collections.shuffle (digits);
// take the first 4 elements of the List
int numbers[] = new int[4];
for(int i=0;i<4;i++){
    numbers[i] = digits.get(i);
}

9voto

Amer Qarabsa Points 4354

Vous pouvez utiliser Set pour cela, l'idée est de générer votre nombre aléatoire puis de le mettre dans un ensemble et de continuer à faire cela jusqu'à ce que vous ayez 4 éléments dans votre ensemble, quand c'est fait vous aurez 4 nombres aléatoires uniques stockés dans votre ensemble.

Set<Integer> randomSet = new HashSet<>();

while(randomSet.size() <4) 
   randomSet.add //add your generated random number

7voto

escitalopram Points 2462

Si vous pouvez créer une fonction rapide f qui fait correspondre les nombres naturels à l'ensemble des nombres qui répondent à votre exigence, vous pouvez générer un seul nombre aléatoire. Votre temps d'exécution est alors limité par f. Pour autant que vous puissiez créer une fonction f raisonnablement rapide, c'est la manière la plus efficace de procéder.

La solution la plus simple consiste à placer tous les numéros qui satisfont à votre critère dans un tableau et à créer un numéro aléatoire comme index dans ce tableau. -> O(1)

7voto

stefan bachert Points 4698

Comme vous le voyez, il existe de nombreuses façons d'atteindre votre objectif. Voici ma proposition

Random random = new Random();

// prepare all valid digits
List<Integer> from = new ArrayList<Integer>(Arrays.asList(0,1,2,3,4,5,6,7,8,9));

// take set in an random order
int numbers[] = new int[4];
for(int i = 0; i < numbers.length; i++){
    numbers[i] = from.remove (random.nextInt (from.size()));
}

for (int num : numbers) {
   System.out.println(num); // when you prefer this
}

0voto

sadasidha Points 668

EDIT

Puisque Collections.shuffle utilise également l'algorithme de Fisher-Yates. Mais cette variante choisit le point de départ de la séquence de façon radicale. C'est comme mélanger un jeu de cartes et choisir 4 cartes du milieu ou mélanger un jeu de cartes et choisir 4 cartes du haut.

Voici une variante de l'algorithme de brassage de Fisher-Yeats mentionnée ici. https://softwareengineering.stackexchange.com/questions/199644/efficient-way-to-shuffle-objects

    public int[] shuffle() {
        int a[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
        Random r = new Random();
        for (int i = a.length; i > 1; i--) {
            swap(a, i - 1, r.nextInt(i));
        }

        int[] result = new int[4];
        // Variant :: Randomly choosing the starting point of the 
        // sequence, since we need only four number.
        System.arraycopy(a, r.nextInt(a.length - 4), result, 0, 4);
        return result;
    }

    private void swap(int[] a, int i, int i1) {
        int temp = a[i];
        a[i] = a[i1];
        a[i1] = temp;
    }

Référence : https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X