Generate random number without duplicate in certain range
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 <>
.
amln_ndh
A girl who has love hate relationship with programming and networking
Updated on June 15, 2022Comments
-
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 over 10 yearsIt is definitely not most efficient way due to failed tries.
-
ucsunil over 10 yearsThe 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 over 10 yearsThere is no point to use Math.random() to get unique integers. Even random ones are recommended to be obtained with Random.nextInt().
-
Digital_Reality over 10 yearsTo generate between 3-5 you must use condition i<=5
-
Bohemian over 10 years@Digital_Reality Doh! Thx.
-
SOFe over 7 yearsIn Java 8 you can use
IntStream.range(3, 6).collect(Collectors.toList())
-
SOFe over 7 yearsAre you sure you want to instantiate a new instance of
Random
each time? -
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 over 7 yearsThat's why you should move the
Random
line out of the loop.