在Java中生成范围内的非重复随机数

时间:2012-12-13 14:54:48

标签: java random non-repetitive

我想生成1到4,4范围内的随机数,包括。
这是我的代码:

int num = r.nextInt(4) + 1;  //r is instance of Random.

但是,我在循环中运行上面的代码,不想重复随机数。 现在发生的事情往往是我得到的:
    1,1,1,2,3,1,4,2,2,1,4,2,4,4,2,1,4,3,3,1,4,2,4,1作为我的输出。

这里,虽然数字在范围(1-4)内是随机的,但经常像前3次迭代中的数字“1”一样重复。

我正在寻找的是一种在循环中获得非重复随机数的方法。 我知道的一个简单方法是在当前迭代之前保留最后一个随机数并进行比较,但我相信必须有更好的解决方案。
提前谢谢。

4 个答案:

答案 0 :(得分:7)

使用random.nextInt(range-1),然后将该数字映射到输出数字,其功能不包括前一个数字:

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());
  }
}

答案 1 :(得分:1)

由于您拥有的数字超出了您的选择范围,因此您必须重复一些数字。您所能做的就是尽量减少重复次数。

执行此操作的一种方法是使用Collections.shuffle,它允许您以随机顺序包含数字,而不重复,并且每次都执行此操作。您可以阻止重复上一个N值。

要停止连续重复的数字,您可以缩小范围并使用模数。

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.
}

由于您排除了最后使用的值,因此实际上只有max-1个可能的值。

答案 2 :(得分:1)

没有“更好”的答案。 您正在获取随机号码。检查这一行:

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

这个可以完全随机。 所以我建议你描述一个更好的要求。 你想要一个与前一个不同的下一个号码吗?你想在一个特殊的响铃中最多重复吗?让我们说连续6个数字,每个数字都允许发生两次?

如果您提出这样的要求,我们可能会帮助您。否则我们可以说:你看到的是非常随机的:)

答案 3 :(得分:0)

这是一个算法:

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)

想象一下A是一包数字为1-4的球。循环的每次迭代,你移除一个球。您可以简单地将球隐藏在数组的末尾,而不是实际从数组中删除。当您减少球袋中的球数(Acnt)时,您选择的下一个球来自非隐藏球。

如果您没有更多球可供选择,您可以通过将球袋中的球数重新设置为完全计数来取消隐藏球。

这基本上是标准的混洗算法。

编辑:重新阅读问题,我现在看到他只允许在1个数字后重复,而不是整个序列,在这种情况下,你需要做的就是改变它,如果(Acnt = = 0)到if(Acnt == length(A) - 1)。