生成不重複隨機數序列(Java)
阿新 • • 發佈:2018-12-10
從1到n之間抽取出k個不重複的隨機數,用Math.random()實現的話,可參照下面的程式碼。
int r = (int) (Math.random() * n), 生成下標,據此下標,去到numbers數組裡拿到隨機數。然後將numbers[r]的值設定成numbers[n-1]的值,下次抽取時,從numbers陣列的前n-1個元素裡抽取。以此類推,再下次,就是從umbers陣列的前n-2個元素裡抽取,直到抽完k個為止。
每次生成的下標是有可能重複的,但是由於numbers數組裡該下標對應的值每抽中一次,就被踢出去了(替換成了n-1位置上的值),所以最終結果並不會重複。interesting…
公司年會抽獎,可以這種方法,將numbers陣列初始化成在職的員工號序列即可:-)
package com.company;
import java.util.Arrays;
import java.util.Scanner;
public class LotteryDrawing {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("How many numbers do you need to draw?" );
int k = in.nextInt();
System.out.println("What is the highest number you can draw?");
int n = in.nextInt();
int[] numbers = new int[n];
for(int i = 0; i < n; i ++)
numbers[i] = i + 1;
int[] result = new int[k];
for(int i = 0; i < result.length; i ++){
//Math.random() generate double that between 0 and 1 (0 included, 1 not included)
//int r represents the index that between 0 and n-1 (both included)
int r = (int) (Math.random() * n);
result[i] = numbers[r];
numbers[r] = numbers[n-1];
n --;
}
Arrays.sort(result);
System.out.println("Lucky numbers: ");
for(int i : result)
System.out.println(i);
}
}
程式輸出:
How many numbers do you need to draw?
6
What is the highest number you can draw?
20
Lucky numbers:
1
2
10
16
17
18
Java還有個Random類,用這個類也可以實現上述目標,基本思想是一樣的。
package com.company;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Random;
import java.util.Scanner;
import java.util.List;
public class LotteryDrawing {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("How many numbers do you need to draw?");
int k = in.nextInt();
System.out.println("What is the highest number you can draw?");
int n = in.nextInt();
List<Integer> numbers = new ArrayList<>();
for(int i = 0; i < n; i ++)
numbers.add(i + 1);
int[] result = new int[k];
for(int i = 0; i < k; i ++){
int r = generateRandomIndex(n - i);
result[i] = numbers.get(r);
numbers.remove(r);
}
Arrays.sort(result);
System.out.println("Lucky numbers: ");
for(int i : result)
System.out.println(i);
}
private static int generateRandomIndex(int n){
Random random = new Random();
//return an int that between 0 and n, 0 included, n not included
return random.nextInt(n);
}
}
程式輸出:
How many numbers do you need to draw?
6
What is the highest number you can draw?
20
Lucky numbers:
6
7
8
11
12
13
在建立Random例項時,如果給定一個種子數字,那麼這個例項生成出來的序列是一定的。比如,給定種子數字1,每一次執行時,它生成出來的序列都是5,8,7,3,4。
Random random = new Random(1);
System.out.println(random.nextInt(10));
System.out.println(random.nextInt(10));
System.out.println(random.nextInt(10));
System.out.println(random.nextInt(10));
System.out.println(random.nextInt(10));
程式輸出:
5
8
7
3
4
如果想要每次的序列不一樣,那麼新建例項時不要給種子數字,它會用系統時間作為種子數字(高併發的情況下,亦不能保證每次呼叫時系統時間都不一樣…)
Random random = new Random();
System.out.println(random.nextInt(10));
System.out.println(random.nextInt(10));
System.out.println(random.nextInt(10));
System.out.println(random.nextInt(10));
System.out.println(random.nextInt(10));
第一次執行時程式輸出:
7
9
4
0
3
第二次執行時程式輸出
8
9
9
4
0