创建没有重复的随机数 [英] Creating random numbers with no duplicates

查看:87
本文介绍了创建没有重复的随机数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在这种情况下,MAX只有5,所以我可以逐个检查重复项,但是我怎么能以更简单的方式做到这一点呢?例如,如果MAX的值为20,该怎么办?
谢谢。

In this case, the MAX is only 5, so I could check the duplicates one by one, but how could I do this in a simpler way? For example, what if the MAX has a value of 20? Thanks.

int MAX = 5;

for (i = 1 , i <= MAX; i++)
{
        drawNum[1] = (int)(Math.random()*MAX)+1;

        while (drawNum[2] == drawNum[1])
        {
             drawNum[2] = (int)(Math.random()*MAX)+1;
        }
        while ((drawNum[3] == drawNum[1]) || (drawNum[3] == drawNum[2]) )
        {
             drawNum[3] = (int)(Math.random()*MAX)+1;
        }
        while ((drawNum[4] == drawNum[1]) || (drawNum[4] == drawNum[2]) || (drawNum[4] == drawNum[3]) )
        {
             drawNum[4] = (int)(Math.random()*MAX)+1;
        }
        while ((drawNum[5] == drawNum[1]) ||
               (drawNum[5] == drawNum[2]) ||
               (drawNum[5] == drawNum[3]) ||
               (drawNum[5] == drawNum[4]) )
        {
             drawNum[5] = (int)(Math.random()*MAX)+1;
        }

}


推荐答案

最简单的方法是创建一个可能的数字列表(1..20或其他),然后用 Collections.shuffle 对它们进行随机播放。然后只需要你想要的许多元素。如果您的范围等于最终所需的元素数量(例如,用于洗牌一副牌),这是非常好的。

The simplest way would be to create a list of the possible numbers (1..20 or whatever) and then shuffle them with Collections.shuffle. Then just take however many elements you want. This is great if your range is equal to the number of elements you need in the end (e.g. for shuffling a deck of cards).

这不能很好地工作如果你想要(比方说)10个随机元素在1..10,000范围内 - 你最终会不必要地做很多工作。此时,最好保留到目前为止生成的一组值,并且只是在循环中生成数字,直到下一个尚未出现:

That doesn't work so well if you want (say) 10 random elements in the range 1..10,000 - you'd end up doing a lot of work unnecessarily. At that point, it's probably better to keep a set of values you've generated so far, and just keep generating numbers in a loop until the next one isn't already present:

if (max < numbersNeeded)
{
    throw new IllegalArgumentException("Can't ask for more numbers than are available");
}
Random rng = new Random(); // Ideally just create one instance globally
// Note: use LinkedHashSet to maintain insertion order
Set<Integer> generated = new LinkedHashSet<Integer>();
while (generated.size() < numbersNeeded)
{
    Integer next = rng.nextInt(max) + 1;
    // As we're adding to a set, this will automatically do a containment check
    generated.add(next);
}

小心选择套装 - 我非常刻意使用 LinkedHashSet 因为它维护了我们关心的插入顺序。

Be careful with the set choice though - I've very deliberately used LinkedHashSet as it maintains insertion order, which we care about here.

另一种选择是总是通过每次缩小范围并补偿现有值来取得进展。因此,例如,假设您想要0到9范围内的3个值。在第一次迭代中,您将生成0..9范围内的任何数字 - 假设您生成一个4。

Yet another option is to always make progress, by reducing the range each time and compensating for existing values. So for example, suppose you wanted 3 values in the range 0..9. On the first iteration you'd generate any number in the range 0..9 - let's say you generate a 4.

在第二次迭代中,您将生成一个数字在0..8范围内。如果生成的数字小于4,则按原样保留...否则添加一个。这会得到0到9的结果范围而不是4.假设我们得到7那样。

On the second iteration you'd then generate a number in the range 0..8. If the generated number is less than 4, you'd keep it as is... otherwise you add one to it. That gets you a result range of 0..9 without 4. Suppose we get 7 that way.

在第三次迭代中,你将生成0范围内的数字..7。如果生成的数字小于4,则保持原样。如果它是4或5,你就加一个。如果它是6或7,你将添加两个。这样结果范围是0..9,没有4或6。

On the third iteration you'd generate a number in the range 0..7. If the generated number is less than 4, you'd keep it as is. If it's 4 or 5, you'd add one. If it's 6 or 7, you'd add two. That way the result range is 0..9 without 4 or 6.

这篇关于创建没有重复的随机数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆