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

我想生成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”那样重复。

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

使用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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 

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

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

因为你有更多的数字,你必须重复一些数字。 您所能做的就是尽量减少重复次数。

一种方法是使用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可能的值。

这是一个算法:

使用数字1-4初始化数组A [4]
设置一个计数器Acnt,有效大小为A.初始化为4
 for i in 1 to length(输出序列)
   选择从0到Acnt -1的随机整数X.
   将A [X]保存到输出序列
   交换(A [X],A [Acnt  -  1])
    Acnt--
    if(Acnt == 0)Acnt = lengh(A)

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

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

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

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