Reputation: 617
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);
}
}
Upvotes: 2
Views: 13801
Reputation: 427
Integer[] a = new Integer[3];
Random r = new Random();
for (int i = 0; i < a.length; i++) {
a[i] = r.nextInt(3-1) + 1;
}
Collections.shuffle(Arrays.asList(a), r);
Upvotes: 0
Reputation: 424993
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);
Upvotes: 10
Reputation: 8214
Reduce the total amount every run, and appropriately increment the result.
static int[] randomRange(Random random, int cap, int count) {
assert count < cap && count > 0 && cap > 0;
int[] output = new int[count];
// initial placeholder. use 0x7FFFFFFF for convenience is also OK.
Arrays.fill(output, -1);
for(int i = 0; i < count; i++) {
// you only have (cap - i) options left
int r = random.nextInt(cap - i);
// iterate through a sorted array
for(int got : output) {
// ignore placeholders
if(got != -1 && got <= r) {
// the generated random int counts number of not-yet-picked ints
r++;
}
}
// add to array in a sorted manner
addToArray(output, r);
}
return output;
}
static void addToArray(int[] array, int value) {
for(int i = 1; i <= array.length; i++) {
if(i == array.length || array[i] >= value) {
// shift smaller values one place left
// this includes -1. If you use 0x7FFFFFFF,
// you may have to sort the array the other way round.
System.arraycopy(array, 1, array, 0, i - 1);
array[i - 1] = value;
return;
}
}
}
This algorithm has a disadvantage that its output is sorted. It is, of course, also possible to keep track of two arrays, one sorted (for increment) and one unsorted (for return).
The above code snippet was tested through cap = 20, count = 10
and cap = 20, count = 20
twice each.
Upvotes: 0
Reputation: 2530
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()+ " ");
}
Upvotes: 1
Reputation: 24998
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 <>
.
Upvotes: 1
Reputation: 116
You can also use Random number generation to fill a HashSet for a fixed range.
Upvotes: 0
Reputation: 84
int base = (int)Math.random();
System.out.print(base);
int change = ((int)Math.random()) % 3;
if(change == 0) {
change++;
System.out.print(base + 1);
System.out.println(base + 2);
}
else {
System.out.print(base + 2);
System.out.println(base + 1);
}
Upvotes: 0
Reputation: 7494
The best possible and most efficient way to generate and store unique numbers would be to create a HashSet that holds your data. Generate the number and then try to add it to the HashSet. If the add method returns false, then it means that the number already exists in the set and hence re-generate a number. The advantage of using this method over the ArrayList is that this has a time complexity of O(1) while using the contains() method (from ArrayList) would result in a time complexity of O(n) - efficiency decreases as size increases.
Upvotes: 0
Reputation: 384
The formula to generate random number in the range is :
Random rn = new Random();
int range = maximum - minimum + 1;
int randomNum = rn.nextInt(range) + minimum;
so in one line you can generate as like this
int num1 = new Random().nextInt(3-1+1) + 1;
int num2 = new Random().nextInt(4-2+1) + 1;
int num3 = new Random().nextInt(5-2+1) + 1;
or
num[i] = new Random.nextInt(range[i]) + 1 + i;
and then you can do your logic stuff to set the resource. Happy Coding :)
Upvotes: 0
Reputation: 151
To get numbers ranging from 1-3, 2-4, 3-5, etc, change this
num[i] = (int)(Math.random()*3);
to this
num[i] = rand.nextInt(2) + 1 + i;
You'll need to import Random
and add Random rand = new Random();
before using it.
Upvotes: 0