I want to generate random numbers, but don't want them to be from excludeRows
array. Here is my code.
public int generateRandom(int start, int end, ArrayList<Integer> excludeRows) {
Random rand = new Random();
int range = end - start +1 - excludeRows.size();
int random = rand.nextInt(range) + 1;
for(int i = 0; i < exclude.size(); i++) {
if(excludeRows.get(i) > random) {
return random;
}
random++;
}
return random;
}
I use this function in a while loop, and during each iteration I add a new value to excludeRows
.
Sometimes it returns numbers that belong to excludeRows
. What's the problem?
Try this every time it will return the value that is not in exclude.
You check:
and if only the first is larger, you'll return the value. Are you sure
exclude
is sorted?You can use
if(exclude.contains(random ))
or the following algorithm:if
(end-start)
is a reasonable number, and you need almost all values you can create a list of all acceptable numbers and use random on this list size and choose the random value as an index. then remove the unwanted number from the list and get another random index.Actually, we do not need to use
contains(random)
with a while loop.To simplify the question, let's see what happens if we only have one excluding value. We can split the result to
2
parts. Then the number of possible values isrange-1
. If the random number is less than the excluded value, just return it. Otherwise, we could add1
.For multiple excluding values, We can split the result set into
size+1
parts, wheresize
means the number of excluding values. Then the number of possible values isrange-size
. Then we sort excluding values in ascending order. If random number is less than the excluding value minusi
, then we just return the random number addi
, wherei
is the index of the the excluding value.I think there are some mistakes.
1) Range should be end - start + 1, because this is the range wanted.
2) If you really want random numbers (as "random" as possible on computers) then you shouldn't just get the next available number. Because in this case your random number will bear the characteristics of excluded numbers density/frequency.
UPDATE
With Achintya Jha's answer my code could be improved (but note there are some remarks as well):