0

Probably a simple task for you guys, however I'm really struggling to make it work. I'm creating a method that can return random integers from 0-30. But I want to make sure, that the same numbers are not used twice. Therefore I created an array called UsedNumbersArray to keep track of everything.

My idea is that first it generates a random number, then it checks the array one by one using a for loop, to see if it's there. If that's the case, it must replace the value with zero, making sure that it won't be found again.

However what's weird is that it replaces a totally different number in the array than the one with our random number. Check out my code:

    private static int checkIfNumberUsed(){

    int questionNumber = randomNumberInRange(1,questionsWithAnswers[0].length); // create random number

    boolean hasNotBeenUsed = false;

    while (!hasNotBeenUsed){ // as long it HAS been used, it will continue to run the loop and create a random num till it gets what it wants

        for (int i = 0; i < questionsWithAnswers[0].length ; i++) { // check if it has been used before

            if (questionNumber==usedNumbersArray[i]){

                usedNumbersArray[i]=0; // will replace the number with 0 so that it can't be found and used again
                hasNotBeenUsed=true; // will exit the loop

            }

        }

        questionNumber = randomNumberInRange(1,questionsWithAnswers[0].length); // if no matches are found it will generate a new random number

    }


    return questionNumber;

Here's the output:

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]

8 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 0, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]

As you can see. The random number is 8, but it has replaced 18 with 0 instead of 8 as it was supposed to?

Hope you can figure this out. Thanks in advance

  • 2
    The typical approach is to shuffle the array and simply iterate. You may want to try that as it's simpler. – assylias Nov 16 '18 at 14:51
  • 1
    A different approach would be to populate the array (or List), then shuffle it. Each request would move a tracked index to the next element. When the index has reached the length of the array, reset back to 0, and shuffle again. – Andrew S Nov 16 '18 at 14:54
  • Possible duplicate of [Random shuffling of an array](https://stackoverflow.com/questions/1519736/random-shuffling-of-an-array) – pjs Nov 16 '18 at 14:59
  • what happend in your code is for that first time it would have generated 18 it was there in array so it replaced it with 0 ..then next random number (at the end of while loop) was generated as 8 which you see in outpput . If you want to verify it just print the nubmer right after it is generated. – Nawnit Sen Nov 16 '18 at 15:01

2 Answers2

1

you don't have to iterate the array yourself. use a List.remove(int index). For example:

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

public class Pool {

    private final Random r = new Random();
    private final List<Integer> pool;

    Pool(int size) {
        pool = new ArrayList<>(size);
        for (int i = 0; i < size; ++i) {
            pool.add(i);
        }
    }

    boolean isNotEmpty() {
        return !pool.isEmpty();
    }

    int nextInt() {
        int i = r.nextInt(pool.size());
        return pool.remove(i);
    }

    public static void main(String[] args) {
        Pool pool = new Pool(30);
        while (pool.isNotEmpty()) {
            System.out.println(pool.nextInt());
        }
    }
}
1

I propose a different solution, one in which you do not fight the language but take advatage of its functionality. The idea is to used a List instead of an array and remove values as they are being used up:

import java.util.ArrayList;
import java.util.Collections;

import static java.lang.Integer.valueOf;
import static java.util.stream.Collectors.toList;
import static java.util.stream.IntStream.range;

public class Randoms {
    private final ArrayList<Integer> randomList;

    public Randoms(int size) {
        randomList = (ArrayList<Integer>)range(0, size).boxed().collect(toList());
        Collections.shuffle(randomList);
    }

    public int nextValue() {
        return randomList.remove(0);
    }

    public static void main(String[] args) {
        int size = 30;
        Randoms r = new Randoms(size);
        for (int i = 0; i < size; i++) {
            System.out.println(r.nextValue());
        }
    }
}

You will need to decide what to do if/when you run out of random values

David Soroko
  • 8,521
  • 2
  • 39
  • 51