1

Possible Duplicate:
Generating Unique Random Numbers in Java

Code will generate 6 random numbers from a range but need them to be unique been melting my brain any pointers would be greatly appreciated

import java.util.Random;
import java.util.Arrays;
public class numbers
{
private int[] lottoNumbers;
private int nextInt;
private Random r;

public numbers()
{
    lottoNumbers = new int [6];
    r = new Random();
    nextInt();
}
public void nextInt()
{
    System.out.print("***     ");
    for (int i = 0; i < lottoNumbers.length; i++)
    {
        lottoNumbers[i] = r.nextInt(49) +1;
        System.out.print(" " + lottoNumbers[i]);
    }
    System.out.println("     ***");
}
}
Community
  • 1
  • 1
user1946316
  • 13
  • 1
  • 3

7 Answers7

6

For each of the six numbers, you need to compare it against the already-generated numbers. If it's the same as any of them, you need to keep trying.

NPE
  • 486,780
  • 108
  • 951
  • 1,012
4

You can simply use the shuffle method and return the 6 first elements after shuffling:

// Create the list of possible numbers
List<Integer> numbers = new ArrayList<Integer>(50);
for(int i = 1 ; i <= 50 ; ++i) {
    numbers.add(i); 
}
// Shuffle the list
Collections.shuffle(numbers);

// Print the numbers
int count = 0;
for(int number : numbers) {
    System.out.println("Random number " + count + ": " + number);
    ++count; // break if count == 6?
}

The advantage of this method is that it runs in linear time (the time taken by the shuffle). You avoid picking x times (x can be very big) an element and checking if it has already been picked!

Jean Logeart
  • 52,687
  • 11
  • 83
  • 118
  • Worth bearing in mind that a linear congruential random number generator will never generate the same number twice until it repeats - and it will be designed to have a long period before looping. – dty Jan 04 '13 at 14:37
  • It is not really relevant. What if you need to pick Integer.MAX_VALUE / 2 out of a list of the first Integer.MAX_VALUE integers? Randomly picking can take forever. – Jean Logeart Jan 04 '13 at 14:39
  • Why would it take any longer than putting all `Integer.MAX_VALUE` values into a list and shuffling it? Your answer suggests that the performance problem you have is that you could potentially randomly select (and therefore discard) the same number multiple times. I'm pointing out that unless you're trying to generate more numbers than the period of the RNG, you won't generate any collisions (at least if the RNG is a LCG). – dty Jan 04 '13 at 14:45
2

You need to add a loop that checks if a number exists among the items that you have already added. Define a boolean variable, set it to false, and go through the loop comparing the existing numbers against the newly generated one. If you see a duplicate, set the boolean to true. Once the loop is over, check your boolean to see if the new number has to be added or not.

int i = 0;
do {
    int next = r.nextInt(49) + 1;
    boolean seen = false;
    for (int j = 0 ; j != i ; j++) {
        if (lottoNumbers[j] == next) {
            seen = true;
            break;
        }
    }
    if (!seen) {
        lottoNumbers[i++] = next;
        System.out.print(" " + next);
    }
} while (i != lottoNumbers.length);

A better solution would involve using a Set<Integer>, but that is probably an advanced topic at this stage.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
1

Just use a Set (thanks to @dty for the improved version!):

private static final Random RND = new Random();
private static final int COUNT = 6;

public int[] getRandomNumbers()
{
    final Set<Integer> set = new HashSet<Integer>(COUNT);

    /*
     * This works: .add() will not add the same element twice. As such, we just
     * need to check that the set has the expected size.
     */
    while (set.size() < COUNT)
        set.add(RND.nextInt());

    return set.toArray(new int[COUNT]);
}
fge
  • 119,121
  • 33
  • 254
  • 329
  • 1
    You can simplify this by testing `set.size()` instead of keeping the `generated` counter. And you also don't need the `i` temporary variable. You end up with something like `while (set.size() < COUNT) { set.add(RND.nextInt()); }` – dty Jan 04 '13 at 14:35
0
public void nextInt()
{
    System.out.print("***     ");
    for (int i = 0; i < lottoNumbers.length; i++)
    {
        int temp;

        // check random int doesn't already exist (embedded assignment below)           
        // NOTE: while loop has empty body, note {} in line below
        while (Arrays.asList(lottoNumbers).contains(temp = r.nextInt(49)+1)){}

        lottoNumbers[i] = temp;
        System.out.print(" " + lottoNumbers[i]);
    }
    System.out.println("     ***");
}
xagyg
  • 9,562
  • 2
  • 32
  • 29
0

I like the set approach but the example can be stremlined a bit

private static final Random RND = new Random();

public static Set<Integer> getRandomNumbers(int count) {
    final Set<Integer> set = new HashSet<>(count);
    while (set.size() < count) {
      set.add(RND.nextInt());
    }
    return set;
}
David Soroko
  • 8,521
  • 2
  • 39
  • 51
0

How about this way?

package rabdomnumbers;

    import java.util.ArrayList;
    import java.util.List;

    public class RabdomNumbers {
    public static int SIZE = 6;

      public static void main(String[] args) {
        Number[] numbers = new Number[SIZE];
        // set an array
    for (int x = 0; x < SIZE; x++) {
      numbers[x] = new Number();
    }
    // sort an array
    for (int x = 0; x < SIZE-1; x++) {
      for (int y = x + 1; y < SIZE; y++) {
        if (numbers[x].getNumber() > numbers[y].getNumber()) {
          Number buf = numbers[x];
          numbers[x] = numbers[y];
          numbers[y] = buf;
        }
      }
    }
    // print an array
    for (int x = 0; x < SIZE; x++) {
      System.out.println("" + numbers[x].getIndex());
    }
  }
}

Where Number is a simple class:

package rabdomnumbers;

import java.util.Random;

public class Number {
  private int index = 0;
  private int number = 0;
  private static int count = 0;
  private final static Random RND = new Random();

  public int getIndex() {
    return index;
  } 

  public int getNumber() {
    return number;
  }

  public Number() {
    index = count++;
    number = RND.nextInt();
  }
}
gooamoko
  • 658
  • 12
  • 32