[英]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.