簡體   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