Generate random number without duplicate in certain range

13,364

Solution 1

Create a list if all numbers in the range, then shuffle the list:

List<Integer> numbers = new ArrayList<>();
// eg for range 3-5
for (int i = 3; i <= 5; i++)
    numbers.add(i);
Collections.shuffle(numbers);

Now use them in their new (random) order.

Unless your range is very large (millions) this will work fine.


Java8 version:

List<Integer> numbers = IntStream.rangeClosed(3, 5).boxed().collect(Collectors.toList());
Collections.shuffle(numbers);

Solution 2

I know it's late, but could be helpful for future reference. You can create your own custom Random class:

//Generates random integers without repetition between two given numbers both inclusive
public class Random {
    private int start;
    private int end;
    private Stack<Integer> numbers = new Stack<>();
    public Random(int start, int end){
        this.start = start;
        this.end = end;
    }
    private void loadNumbers(){
         for (int i=start;i<=end;i++){
                numbers.push(i);
            }
         Collections.shuffle(numbers);
    }
    public int nextInt(){
        if (numbers.empty()) loadNumbers();
        return numbers.pop();
    }
}

And use it like:

Random rand = new Random(1,20);
for(int i=0; i<100;i++){
    System.out.print(rand.nextInt()+ " ");
}

Solution 3

Well, you could store your numbers an an ArrayList<>. Every time you generate a random number, see if the ArrayList<> contains the number. If it does, generate another number and repeat the process.

Better yet, use a Set <>.

Share:
13,364
amln_ndh
Author by

amln_ndh

A girl who has love hate relationship with programming and networking

Updated on June 15, 2022

Comments

  • amln_ndh
    amln_ndh almost 2 years

    I'm currently creating an app and it will generate random numbers. So each time it will generate three numbers num1, num2 and num3. These number should not be duplicate. For example if num1 = 1 than num2 and num3 cannot be equal to 1. I've tried this code where it will display three different number ranging from 0-2. And its working. However I would want to generate random number ranging from 1-3, 2-4, 3-5 and so on. So how can I achieve this by using the code below. Please help me since I'm new to this. Thank you.

    for(int i=0; i<images.length; i++)
    {
            num[i] = (int)(Math.random()*3);
    
            if (i == 0)
            {
            if(num[i]== 0)
                images[i].setImageResource(R.drawable.zero);
            else if(num[i]==1)
                images[i].setImageResource(R.drawable.one);
            else
                images[i].setImageResource(R.drawable.two);
            }
    
            else
            {
                while (num[i] ==  num[i-1] || num[i] == num[0] )
                    num[i] = (int)(Math.random()*3);
    
    
            if(num[i]==0)
                images[i].setImageResource(R.drawable.zero);
            else if(num[i]==1)
                images[i].setImageResource(R.drawable.one);
            else
                images[i].setImageResource(R.drawable.two);
    
            }
        }
    
  • Basilevs
    Basilevs over 10 years
    It is definitely not most efficient way due to failed tries.
  • ucsunil
    ucsunil over 10 years
    The ideal case would be to generate numbers that are known to be unique but this would not be possible with Math.random(). I think the OP wanted to stick as close as possible to his original code. My priority was the fastest way to find out of the number was unique given that you are using Math.random().
  • Basilevs
    Basilevs over 10 years
    There is no point to use Math.random() to get unique integers. Even random ones are recommended to be obtained with Random.nextInt().
  • Digital_Reality
    Digital_Reality over 10 years
    To generate between 3-5 you must use condition i<=5
  • Bohemian
    Bohemian over 10 years
    @Digital_Reality Doh! Thx.
  • SOFe
    SOFe over 7 years
    In Java 8 you can use IntStream.range(3, 6).collect(Collectors.toList())
  • SOFe
    SOFe over 7 years
    Are you sure you want to instantiate a new instance of Random each time?
  • Bohemian
    Bohemian over 7 years
    @PEMapModder not quite. You can't collect an IntStream, and rangeClosed is more appropriate for the context. See my undated answer.
  • SOFe
    SOFe over 7 years
    That's why you should move the Random line out of the loop.