如何在java中生成6个不同的随机数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22584244/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 16:38:56  来源:igfitidea点击:

How to generate 6 different random numbers in java

javaarraysmathrandom

提问by coding

I want to generate 6 different random numbers by using Math.random and store them into an array. How can I make sure that they are different? I know I need to use for-loop to check the array but how...

我想通过使用 Math.random 生成 6 个不同的随机数并将它们存储到一个数组中。我如何确保它们是不同的?我知道我需要使用 for 循环来检查数组,但是如何...

This is the range. I only need numbers between 1 and 49. ( 1 + (int) (Math.random() * 49) )

这是范围。我只需要 1 到 49 之间的数字。( 1 + (int) (Math.random() * 49) )

回答by peter.petrov

Generate any 6 numbers (not necessarily different). Order them.

生成任意 6 个数字(不一定不同)。订购它们。

a1 <= a2 <= a3 <= a4 <= a5 <= a6

a1 <= a2 <= a3 <= a4 <= a5 <= a6

Now take these 6 numbers

现在拿这6个数字

a1 < a2 + 1 < a3 + 2 < a4 + 3 < a5 + 4 < a6 + 5

a1 < a2 + 1 < a3 + 2 < a4 + 3 < a5 + 4 < a6 + 5

These 6 are different and random.

这6个是不同的,随机的。

The idea of this construct comes from some combinatorial proofs.

这个构造的想法来自一些组合证明。

Its advantage is that it's simple, fast, and deterministic.
I think the time complexity is O(count*log(count)).
I wonder if it can be improved.

它的优点是简单、快速和确定性。
我认为时间复杂度是O(count*log(count)).
我想知道是否可以改进。

import java.util.TreeMap;

public class Test005 {

    public static void main(String[] args) {
        int count = 6;
        int min = 1;
        int max = 49;

        // random number mapped to the count of its occurrences
        TreeMap<Integer, Integer> mp = new TreeMap<Integer, Integer>();
        for (int i=0; i<count; i++){
             int d = ( min + (int) (Math.random() * (max-count+1)) );
             if (!mp.containsKey(d)){
                 mp.put(d, 0);
             }
             mp.put(d, mp.get(d) + 1);
        }

        // now ensure the output numbers are different
        int j = 0;
        for (int num : mp.keySet()){
            int cnt = mp.get(num);
            for (int i=0; i<cnt; i++){
                System.out.println(num + j);
                j++;
            }
        }
    }

}

回答by Boris the Spider

In Java 8:

在 Java 8 中:

final int[] ints = new Random().ints(1, 50).distinct().limit(6).toArray();

In Java 7:

在 Java 7 中:

public static void main(final String[] args) throws Exception {
    final Random random = new Random();
    final Set<Integer> intSet = new HashSet<>();
    while (intSet.size() < 6) {
        intSet.add(random.nextInt(49) + 1);
    }
    final int[] ints = new int[intSet.size()];
    final Iterator<Integer> iter = intSet.iterator();
    for (int i = 0; iter.hasNext(); ++i) {
        ints[i] = iter.next();
    }
    System.out.println(Arrays.toString(ints));
}

Just a little messier. Not helped by the fact that it's pretty tedious to unbox the Set<Integer>into an int[].

只是有点乱。的事实,这是非常乏味的拆箱没有帮助Set<Integer>int[]

It should be noted that this solution should be fine of the number of required values is significantly smallerthan the range. As 1..49is quite a lot larger than 6you're fine. Otherwise performance rapidly degrades.

需要注意的是,这种解决方案应该很好的要求值的数量明显小于这个范围。因为1..496你大很多。否则性能会迅速下降。

回答by Alexis C.

You can use a Set.

您可以使用一个Set.

Set<Integer> s = new HashSet<>();
while(s.size() != 6){
   s.add(1 + (int) (Math.random() * 49));
}

Integer[] arr = s.toArray(new Integer[s.size()]);

This is enough to do this in your case because the number of distinct random numbers is relatively small compared to the size of the range you generate them.

这足以在您的情况下执行此操作,因为与您生成的范围的大小相比,不同的随机数的数量相对较小。

Otherwise I would go with @JBNizet approach.

否则我会采用@JBNizet 方法。

回答by JB Nizet

Create a list containing the numbers 1 to 49.

创建一个包含数字 1 到 49 的列表。

Create a random number xbetween 0 and the size of the list, take the number being at index xin the list, and remove it from the list.

创建一个x介于 0 和列表大小之间的随机数,取列表中索引处的数字x,并将其从列表中删除。

Repeat the previous step 5 times. And you're done. Note that java.util.Randomhas a nextInt(int max)method that you should use instead of Math.random().

重复上一步 5 次。你已经完成了。请注意,java.util.Random有一个nextInt(int max)您应该使用的方法而不是Math.random().

Note regarding performance: this solution has an advantage compared to the "try until you get 6 different numbers" various solutions: it runs in a O(n) time. It doesn't matter much for 6 unique numbers out of 50, but if you want to get 48 or 49 unique random numbers out of 50, you'll start seeing a difference, because you might have to generate many random numbers before getting one that isn't already in the set.

关于性能的注意事项:与“尝试直到获得 6 个不同的数字”的各种解决方案相比,此解决方案具有优势:它在 O(n) 时间内运行。对于 50 个中的 6 个唯一数字并不重要,但是如果您想从 50 个中获得 48 个或 49 个唯一随机数,您将开始看到差异,因为在获得一个之前您可能必须生成许多随机数这不是已经在集合中。

EDIT:

编辑:

to reduce the cost induced by the removal of the elements in the list, you could instead simply replace the element at index xwith the last element of the list (and at the second iteration, with the element at size - 2, etc.)

为了减少删除列表中的元素所引起的成本,您可以简单地将 index 处的元素替换x为列表的最后一个元素(并在第二次迭代中,使用大小为 2 的元素等)

回答by Brendan Lesniak

Just keep generating numbers and adding them to the array as long as they are unique; psuedocode:

只要它们是唯一的,就继续生成数字并将它们添加到数组中;伪代码:

num = genNextRand()

For (array length)
    If (num not in array)
        addToArray()

Repeat while length not equal 6

回答by Marko Topolnik

Instead of checking that the array has no duplicates, you can use a bit more smartness while generating the numbers, such that uniqueness is enforced at the outset.

您可以在生成数字时使用更聪明的方法,而不是检查数组是否有重复项,这样从一开始就强制执行唯一性。

  1. Create a boolean[]as long as your range (49 entries);
  2. generate a random number from the full range;
  3. put that number into your output array;
  4. "cross out" the corresponding index in the boolean[];
  5. now generate another random number, but curtail the range by one (now 48);
  6. instead of directly using that number as output, scan your boolean[], counting all the non-crossed entries. Stop when you reach the count equal to the random number generated in step 5. The number corresponding to that entry is your output number;
  7. go to step 4.
  1. 创建一个boolean[]只要你的范围(49 个条目);
  2. 从全范围生成一个随机数;
  3. 将该数字放入您的输出数组中;
  4. “划掉”中的相应索引boolean[]
  5. 现在生成另一个随机数,但将范围缩小一(现在是 48);
  6. 不要直接使用该数字作为输出,而是扫描您的boolean[],计算所有未交叉的条目。当您达到等于步骤 5 中生成的随机数的计数时停止。与该条目对应的数字是您的输出数字;
  7. 转到步骤 4。

回答by usr2564301

Create a variable last; initialize it to 0.

最后创建一个变量;将其初始化为0.

Next, in a loop xfrom 0 to 5, create a random number between last+1and 49-6+x. Store this number in a list, and set lastto the number generated this way.

接下来,在从 0 到 5的循环x 中,在last+1和之间创建一个随机数。将此数字存储在列表中,并设置为以这种方式生成的数字。49-6+xlast

You will end up with an ordered list of 6 random numbers in the range of 1..49 with no repeats.

您最终将得到一个 1..49 范围内 6 个随机数的有序列表,没有重复。

回答by TheLastOfTheMoops

in your case n=6

在你的情况下 n=6

     public static int[] chooseAny(int n){
        int[] lottery = new int[n];
        int[] chooseFrom = new int[49];
        for(int i=1 ; i <= 49 ; i++)
            chooseFrom[i-1] = i;
        Random rand = new Random();
        int N = 49;
        int index;
        for(int i=0 ; i < n ; i++){
            //pick random index
            index = rand.nextInt(N);
            lottery[i] = chooseFrom[index];
            chooseFrom[index] = chooseFrom[N-1];
            N--;
        }
        return lottery;
    }

回答by ar4ers

I've just came up with a small idea for Java 8-.

我刚刚想出了一个关于 Java 8- 的小想法。

Set<Integer> set = new LinkedHashSet<>();
while(set.size() != 6)
    set.add(rnd.nextInt(49) + 1);

回答by Ilya Budu

That code generate numbers from 6 to 0 and save in ArrayList.

该代码生成从 6 到 0 的数字并保存在 ArrayList 中。

If generated number was duplicated the program generate numbers again.

如果生成的数字重复,程序会再次生成数字。

If generated number is different that number is added.

如果生成的数字不同,则添加该数字。

Code:

代码:

private ArrayList<Integer> arraylist = new ArrayList<Integer>();

private Random rand = new Random();

public void insertNumber() {
    while (true) {
        int i = generateNumber();
        if(!isGenerateNumberExists(i)){
            addNumber(i);
            break;
        }
    }
}
//Generate numbers
private int generateNumber() {
    return rand.nextInt(6);
}
//Confirm if that number exists
private boolean isGenerateNumberExists(int y) {
    for (int num : arraylist) {
        if (num == y) {
            return true;
        }
    }
    return false;
}
//Add number to arrayList
private void addNumber(int x) {
    arraylist.add(x);
}