繁体   English   中英

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

[英]How to generate 6 different random numbers in java

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

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

在Java 8中:

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

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

只是有点混乱。 Set<Integer>拆箱为int[]非常繁琐,这无济于事。

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

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

创建一个介于0和列表大小之间的随机数x ,使该数字位于列表中的索引x ,然后将其从列表中删除。

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

关于性能的注意事项:与“尝试直到获得6个不同的数字”各种解决方案相比,该解决方案具有一个优势:它运行时间为O(n)。 50个中的6个唯一数无关紧要,但是如果要从50个中获得48个或49个唯一随机数,就会开始看到差异,因为您可能必须先生成许多随机数,然后才能获得一个尚未包含在集合中。

编辑:

为了减少由于删除列表中的元素而导致的成本,您可以简单地将索引x处的元素替换为列表中的最后一个元素(在第二次迭代中,将元素的大小更改为2,依此类推)。

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

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

现在取这6个数字

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

这6个是不同且随机的。

这种构造的思想来自一些组合证明。

它的优点是简单,快速和确定性。
我认为时间复杂度为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++;
            }
        }
    }

}

您可以使用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()]);

就您的情况而言,这样做就足够了,因为与您生成随机数范围的大小相比,不同随机数的数量相对较小。

否则,我会使用@JBNizet方法。

我刚刚想到了一个Java 8的小主意。

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

您可以在生成数字时使用更多的智能功能,而不是检查数组是否没有重复项,这样一开始就强制要求唯一性。

  1. 创建一个boolean[] ,只要您的范围(49个条目);
  2. 从整个范围生成一个随机数;
  3. 将该数字放入输出数组中;
  4. “划掉” boolean[]的相应索引;
  5. 现在生成另一个随机数,但将范围缩小一个(现在为48);
  6. 而不是直接使用该数字作为输出,而是扫描boolean[] ,计算所有非交叉条目。 当您达到等于在步骤5中生成的随机数的计数时,请停止。
  7. 转到步骤4。

在您的情况下,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;
    }

只要保持生成数字并将它们添加到数组中即可,只要它们是唯一的即可。 伪代码:

num = genNextRand()

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

Repeat while length not equal 6

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

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

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

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

如果生成的号码重复,程序将再次生成号码。

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

码:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM