2015-09-06 212 views
5

我有這種方法爲此方法中列出的每個數組值生成一個數字(1-10)。我希望將整組數字顯示爲一組唯一的數字。這個怎麼做?爲每個數組值生成一個唯一的隨機數

public static int generateNumbers(int[] lotteryNumbers) { 

    Random randNum = new Random(); 

    lotteryNumbers[0] = randNum.nextInt(10); 
    lotteryNumbers[1] = randNum.nextInt(10); 
    lotteryNumbers[2] = randNum.nextInt(10); 
    lotteryNumbers[3] = randNum.nextInt(10); 
    lotteryNumbers[4] = randNum.nextInt(10); 

    return lotteryNumbers[4]; 
} 
+0

你不應該使用隨機。 – 2015-09-06 12:22:00

+2

重複http:// stackoverflow。com/questions/8115722/generated-unique-random-numbers-in-java – Satya

+1

@nikpon「隨機」有什麼問題?這非常好 – Dici

回答

5

一個簡單的解決方案是產生的10位數字的列表,隨機播放某個列表,並獲得所述第一五行:

List<Integer> list = new ArrayList<>(10); 
for (int i = 0; i < 10; i++) { 
    list.add(i); 
} 
Collections.shuffle(list); 
Integer[] lotteryNumbers = list.subList(0, 5).toArray(new Integer[10]); 

Collections.shuffle(list)是隨機的置換代替給定列表中的實用程序方法。

如果您使用的是Java 8,這可以寫爲:

List<Integer> list = IntStream.range(0, 10).boxed().collect(Collectors.toList()); 
Collections.shuffle(list); 
int[] loterryNumbers = list.subList(0, 5).stream().mapToInt(i -> i).toArray(); 
+0

謝謝@Tunkai。但有沒有辦法讓我可以使用隨機生成唯一的數字?因爲我只允許使用隨機,因爲這是一個學校作業。 –

+1

沒有內置的方式。你可以做的是在循環中使用Random生成一個int,直到你之前沒有找到你已經獲得的數字。 – Tunaki

+0

@ N.Cre看到我的答案,它基本上與'Collections.shuffle'算法相同,但不使用庫方法。這是很好的知道,也是對你的任務有好處,但請記住,在現實生活中,Tunaki的答案會更好。我不介意你是否贊成我的做法:D – Dici

3

一個天真的技術是在組隨機挑選你想「洗牌」:

public static int[] generateNumbers(int exclusiveMaxValue) { 
    List<Integer> values = new ArrayList<>(exclusiveMaxValue); 
    for (int i=0 ; i<values.size() ; i++) values.add(i); 

    int[] result = new int[exclusiveMaxValue]; 
    Random rd = new Random(); 
    for (int i=0 ; i<result.length ; i++) { 
     result[i] = values.remove(rd.nextInt(values.size())); 
    } 
    return result; 
} 

然而, List.remove通常是O(n),所以整個方法是二次的,這是非常昂貴的。可以在通過O(n)簡單地交換元件在適當位置執行的混洗(這就是Collections.shuffle一樣):

​​3210
1

此方法生成的在範圍唯一號碼的長度爲N的序列[0,N-1]。

public static int[] generateNumbers(int length) { 
    final int[] array = new int[length]; 
    for (int i = 0; i < length; ++i) { 
     array[i] = i; 
    } 
    shuffle(array); 
    return array; 
} 

洗牌費雪耶茨算法使用:的

public static void shuffle(final int[] array) { 
    final Random random = new Random(); 
    for (int i = array.length - 1; i > 0; --i) { 
     final int randomIdx = random.nextInt(i + 1); 
     final int temp = array[i]; 
     array[i] = array[randomIdx]; 
     array[randomIdx] = temp; 
    } 
} 
  • 感謝(Ronald Fisher and Frank Yates)算法的時間複雜度爲O(n)
  • 此實現適用於陣(圖元)不在集合上(Integer類的實例在對象中包裝基本類型int的值) - 如果數組大小足夠大,這很重要
0

這是一個使用一套並填充它,直到它增長到所需的大小的替代方法。它生成numbersToDraw不同的隨機數字,範圍從分鐘max(含)。它還保留了繪製數字的順序(這就是LinkedHashSet的用途)。

private static Set<Integer> drawNumbers(int min, int max, int numbersToDraw) { 
    if (max < min) { 
     throw new IllegalArgumentException("Minimum must be less than maximum."); 
    } 
    if (max < 0 || min < 0) { 
     throw new IllegalArgumentException("Both range numbers must be positive."); 
    } 
    final int countOfNumbers = max - min + 1; 
    if (countOfNumbers < numbersToDraw) { 
     throw new IllegalArgumentException("Range is not big enough."); 
    } 
    final Random randomizer = new SecureRandom(); 
    final Set<Integer> numbersDrawn = new LinkedHashSet<>(); 
    while (numbersDrawn.size() < numbersToDraw) { 
     final int randomNumber = min + randomizer.nextInt(countOfNumbers); 
     numbersDrawn.add(randomNumber); 
    } 
    return numbersDrawn; 
} 

如果您不需要號碼是唯一的,你可以在Java 8使用:

final Random randomizer = new SecureRandom(); 

final List<Integer> numbersDrawn = IntStream 
     .range(0, numbersToDraw) 
     .mapToObj(i -> min + randomizer.nextInt(max - min + 1)) 
     .collect(Collectors.toList()); 

如果您不需要號碼是唯一的,但你要打印其獨特的價值(是你原來的問題?):

final Random randomizer = new SecureRandom(); 

final Set<Integer> numbersDrawn = IntStream 
     .range(0, numbersToDraw) 
     .mapToObj(i -> min + randomizer.nextInt(max - min + 1)) 
     .collect(Collectors.toSet()); 

併爲您的具體情況多了一個選擇:

final Set<Integer> distinctNumbers = Arrays 
    .stream(lotteryNumbers) 
    .distinct() // you can leave this as the set is distinct automatically 
    .boxed() 
    .collect(Collectors.toSet());