简体   繁体   中英

Drawing six random numbers without repetition on table /java

Hello I have with repetitions in drawing randoms. I tried to do this on tables but every time I have problem with comparing generated random number with numbers in table. Be carefull there because this code now is endless loop what is throwing ArrayIndexOutOfBoundsException. Do you have any ideas? To show you what I want to get is similar to polish TV show Lotto where they are drawing 6 random numbers written on balls without repetition. I have seen topic where it was done on lists but it's possible on tables like that?

public static void main(String[] args) {

    Lotto lot = new Lotto();

    int[] table = new int[6];

    Random random = new Random();

    for(int i = 0; i < 6; i++) {
        int numbers = random.nextInt(48) + 1;
        for(int k = 0; k < 6; k++) {
            if (table[k] != numbers) {
                try {
                    table[i] = numbers;
                } catch (ArrayIndexOutOfBoundsException e){
                    System.out.println(e); 
                } 
            } else {
                i--;
            }
        }
    }

    Arrays.sort(table);

    for (int m = 0; m < 6; m++) {
        System.out.println(table[m]);
    }

}

I suggest following approach:

    // Get list of all number
    List<Integer> all = new ArrayList<>();
    for (int i = 1; i <= 48; i++) {
        all.add(i);
    }

    //Shuffle it
    Collections.shuffle(all);

    //Take first 6
    List<Integer> result = all.subList(0, 6);

There are two popular techniques, choose only items that are available or choose any possible and check if it has been chose. This answer chooses from possible numbers, check if the number has been chosen already. If it has not been chosen, it is added to the array. If it has been chosen, then the process is repeated.

for(int i = 0; i < 6; i++) {
    boolean selected = false;
    while(!selected){
        selected = true;
        int numbers = random.nextInt(48) + 1;
        for(int k = 0; k <= i; k++) {
            if (table[k] == numbers) {
                selected = false;
                break; 
            } 
        }
        if(selected){
           table[i] = numbers;
        } 
    }
}

The usage for the techniques depends on how many samples you need compared to the population you are choosing from.

If you need to choose any six numbers between 1 and 1000000, then this technique will work better because the odds of repeating are small, but shuffling a million element list takes more calculations.

The other technique is more appropriate say if your possible numbers are small, for example if you had to pick 6 numbers between 1 and 7, then you would pick a lot of duplicates. So shuffling a list will be better.

In your range, 6 out of 49, the choose and repeat will be faster because most often you'll find a new number.

I would do it like this:

TreeSet<Integer> t = new TreeSet<>();
while (t.size()<6) {
    t.add((int)(Math.random()*48+1));
}

TreeSet guarantees that only unique items will be put into target collection.

Try and model the real world and get your application to do what happens in real life. You have 48 balls, numbered 1 to 48. Let's make a collection of them:

List<Integer> ballsInTheMachine = new ArrayList<>(48);
for (int i = 1; i <= 48; i++)
    ballsInTheMachine.add(i);

Using Java 8 Streams, you can also create the same list in a way that is supposedly more succinct:

List<Integer> ballsInTheMachine = IntStream.rangeClosed(1, 48)
        .collect(ArrayList::new, ArrayList::add, ArrayList::addAll);

Next, you pick 6 balls at random out of the 48:

Random rng = new Random();
List<Integer> ballsPicked = new ArrayList<>(6);
for (int i = 1; i <= 6; i++) {
    int index = rng.nextInt(ballsInTheMachine.size());
    Integer pickedBall = ballsInTheMachine.remove(index);
    ballsPicked.add(pickedBall);
}

And now you have your 6 randomly chosen balls in the list ballsPicked .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM