-1

How could I make my code does not repeat any number generated randomly, was looking in the forum but can not find any examples that I can easily understand.

import java.util.*;
public class Lottery {
    public static void main(String[] args) {
       int n[] = {37};
       Random rd = new Random();
       for (int i = 0; i < n.length;i++){
            for (int j=0; j <6;j++) {
                System.out.println(rd.nextInt(n[i])+1); 
            }   
       }
    }
}
ErstwhileIII
  • 4,829
  • 2
  • 23
  • 37
  • 2
    save each generated number to an array, then on each loop, check if the newly generated number exists in the array already, if it does, generate another one. this will be a while-loop within the for-loop – user2163298 Aug 23 '14 at 00:32
  • 1
    Put numbers into a map. If key exists, reroll that random number. – AntonH Aug 23 '14 at 00:32

5 Answers5

2

If you have a really wide range of numbers (over 10,000) and depending on how many you need, put the rolled numbers into a set. If key exists, re roll that random number, just as AntonH suggested.

However, if you have a few numbers and are rolling a lot of times, the number of times you hit already rolled values becomes significant.

In this case, store the possible numbers that you want in a list, and then shuffle it.

ArrayList<Integer> numbers = new ArrayList<Integer>(10); 
for (int i = 0; i < numbers.size(); i++) { 
    numbers.add(i); 
} 
Collections.shuffle(numbers);

Then access the list in order for each random number.

nmore
  • 2,474
  • 1
  • 14
  • 21
1

You want a random permutation of N numbers. So, you make an int[] and fill it with 0...max, and then you shuffle it. Several open source libraries provide random shuffle / permutation methods.

bmargulies
  • 97,814
  • 39
  • 186
  • 310
1

When you are writing a program that simulates an object of real life, use the same approach that has been used in real life.

In a lottery you have a set of ordered balls, which are shuffled.

So, make an array, and populate it with numbers from 1 to maxNumber.

Then use class Collections and it's method shuffle to shuffle this array.

That's it.

1

It appears that you want to draw m items randomly from a set of n items. You could create a simple Draw class as shown below and call it "m" times to get successive indexes of items.

package com.example.randomdraw;

import java.util.ArrayList;
import java.util.Random;

public class Draw {
    private Random random = null;
    private ArrayList<Integer> list = new ArrayList<Integer>();

    public Draw(int n) {
        // Make sure list was initialized and items remain
        if (list == null || list.size() < 1) {
             return -1;
        ?
        random = new Random();
        // Establish a list of indexes to be used in returning a draw
        for (int i=0; i<n; i++) {
            list.add(i);
        }
    }
    // return the next random index from the m numbers(0 to m-1)
    public int getNextDraw() {
        // get random number from 0 to the number of remaining items
        int i = random.nextInt(list.size());
        // get the value to return (the ith element from the remaining items
        int result = list.get(i);
        // remove the item to be returned, so it won't be available to draw
        list.remove(i);
        // return the requested result
        return result;
    }
}
ErstwhileIII
  • 4,829
  • 2
  • 23
  • 37
  • Interesting, but how could you avoid that you hit the same index more than once? Wouldn't that end up giving you the same random number? – Edwin Dalorzo Aug 23 '14 at 01:19
  • In the code the random number is not returned, instead the number in the "i"th slot is returned (and then that slot is removed from the list array). Only unique numbers are returned. – ErstwhileIII Aug 23 '14 at 01:24
  • Oh, I had not noticed the `remove`. Now it makes sense to me. I guess you may want to initialize the `ArrayList` in the constructor as well, using an initial capacity of `n`. Otherwise, the loop in the constructor will probably end up copying the internal array of the ArrayList several times before all the random numbers are generated if `n` is big enough. – Edwin Dalorzo Aug 23 '14 at 01:27
  • @Erstwhilell I actually meant `list = new ArrayList<>(n)` which would initialize the array in the `ArrayList` to an initial size of `n`. Otherwise, it's default size is used, and it is quite small. When the array is full, a bigger array is created and all items copied. This takes time, and you could avoid it by initializing the array list size. – Edwin Dalorzo Aug 23 '14 at 15:04
0

Here is implementation that does next random as soon as it gets same number as before:

public class UniqueRandom {
    private Random random = new Random();
    private Set<Integer> usedNumbers = new HashSet(); 

    public int nextInt() {
        int potentialRandom = this.random.nextInt();

        // try while we don't find unique random
        while (this.usedNumbers.contains(potentialRandom)) {
            potentialRandom = this.random.nextInt();
        }

        // reserve found unique random number
        this.usedNumbers.add(potentialRandom);

        return potentialRandom;
    }
}

Basic usage looks like this:

    UniqueRandom uniqueRandom = new UniqueRandom();
    for (int i = 0; i < 20; i++) {
        System.out.println(uniqueRandom.nextInt());
    }
Dejan Pekter
  • 705
  • 3
  • 18