Generate non repeating random number within range in Java

点点圈 提交于 2019-12-04 07:33:51

Use random.nextInt(range-1) and then map that number to the output number with a function that excludes the previous number:

public class Test {
  private final Random random = new Random();
  private final int range;
  private int previous;

  Test(int range) { this.range = range; }

  int nextRnd() {
    if (previous == 0) return previous = random.nextInt(range) + 1;
    final int rnd = random.nextInt(range-1) + 1;
    return previous = (rnd < previous? rnd : rnd + 1);
  }


  public static void main(String[] args) {
    final Test t = new Test(4);
    for (int i = 0; i < 100; i++) System.out.println(t.nextRnd());
  }
}

There is no "better" answer. You are getting a random number. Check this line:

1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1

this could be perfectly random. So I propose you describe a better requirement. Do you want always a next number that is different from the previous? Do you want a maximum of duplicates in a special rang? lets say within 6 consecutive numbers, every number is allowed to occur twice?

If you bring such a requirement we might be able to help you. otherwise we can just say: what you seeing is really random :)

As you have more numbers than you have to choice from you have to repeat some numbers. All you can do is minimise the number of immediate repeats.

One way to do this is to use Collections.shuffle which allow you to have numbers in a random order, without repeats and do this each time. You could prevent the last N value being repeated.

To stop consecutive repeating numbers you can reduce the range and use modulus.

int n = 0, max = 4;
Random rand = new Random();

for(int i = 0; i < numbers; i++) {
   n = (n + rand.nextInt(max-1)) % max;
   int numToUse = n + 1;
   // use this number.
}

This work as there is really only max-1 possible values as you are excluding the last value used.

Here is an algorithm:

initialize an array A[4] with the numbers 1-4
set a counter Acnt, the effective size of A. Initialize to 4
for i in 1 to length(output sequence)
   choose a random integer X from 0 to Acnt -1
   save A[X] to your output sequence
   swap(A[X],A[Acnt - 1])
   Acnt--
   if(Acnt == 0) Acnt = lengh(A)

Imagine A is a bag of balls with the numbers 1-4. Each iteration of your loop, you remove a ball. Rather than actually deleting from the array, which is expenisve, you simply hide the ball at the end of the array. When you decrement the number of balls in the bag (Acnt), the next ball you select comes from the non-hidden balls.

When you have no more balls to select, you unhide the balls by resetting the count of balls in your bag back to the full count.

This is basically the standard shuffle algorithm.

Edit: Rereading the question, I see now he allows repeats after only 1 number instead of the whole sequence, in which case it all you need to do to modify this is change if (Acnt == 0) to if(Acnt == length(A) - 1).

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!