Random number generator without replacement?
I tried to program a random number generator that doesn't generate the same random number more than once. But I cannot and cannot understand why. My code looks like this:
public void printNS(){
System.out.print("Numeros Numeros: ");
for(int i=0; i < 5 ; i++){
System.out.print( (int)(Math.random()*50) + ",");
}
System.out.print("; Numeros Stars: ");
for(int i=0; i < 2 ; i++){
System.out.print( (int)(Math.random()*12)+ ",");
}
}
source to share
in java 8 you can do the following
int[] rand = new Random().ints(start, end).distinct().limit(number).toArray();
for more info / options see doc
And before java 8, you can use Set. Generate random numbers until the size of your set is less than the desired number of random numbers.
source to share
So, you want k
great random numbers from 0
to n
(s k < n
).
Two possible approaches:
-
Pick
k
random numbers as you did and store them in the data structure. Each time you choose a number, check if it is contained in the structure: if so, keep collecting until you get a "new" random number. This is a fairly straightforward approach, but the loop can potentially block your application. I suggest usingSet
as it preserves certain elements by definitionSet<Integer> set = new LinkedHashSet<>(); // unordered while (set.size() < k){ set.add((int)(Math.random()*n)); } System.out.println(set);
-
Create
List
and initialize it with every number between0
andn
. Then shuffle it. The firstk
items in the list are the numbers you want.List<Integer> list = new ArrayList<>(n); for (int i = 0; i < n; i++){ list.add(i); } Collections.shuffle(list); list.subList(0, k).clear(); System.out.println(list);
I would suggest the second approach as it is cleaner, but I don't know your performance requirements.
source to share
Here:
private printStars(int loops, int factor) {
for(int i=0; i < loops ; i++){
System.out.print( (int)(Math.random()*factor) + ",");
}
And now:
public void printNS(){
System.out.print("Numeros Numeros: ");
printStars(5, 50);
System.out.print("; Numeros Stars: ");
printStars(2, 12);
Hope it helps. The key point is: when you iterate over the code, look for those elements that are "identical"; and then move them to another method!
source to share