[英]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..49
比6
大很多,所以您可以。 否則性能會迅速下降。
創建一個包含數字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);
您可以在生成數字時使用更多的智能功能,而不是檢查數組是否沒有重復項,這樣一開始就強制要求唯一性。
boolean[]
,只要您的范圍(49個條目); boolean[]
的相應索引; boolean[]
,計算所有非交叉條目。 當您達到等於在步驟5中生成的隨機數的計數時,請停止。 在您的情況下,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 +1
和49-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.