如何在java中生成6个不同的随机数
我想通过使用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 intSet = new HashSet<>(); while (intSet.size() < 6) { intSet.add(random.nextInt(49) + 1); } final int[] ints = new int[intSet.size()]; final Iterator iter = intSet.iterator(); for (int i = 0; iter.hasNext(); ++i) { ints[i] = iter.next(); } System.out.println(Arrays.toString(ints)); }
只是有点麻烦。 将Set
拆分为int[]
是非常繁琐的事实并没有帮助。
应该注意的是,这种解决方案应该是所需数量的精确值明显小于范围。 由于1..49
比6
大很多,你很好。 否则性能会迅速下降。
创建一个包含数字1到49的列表。
创建一个介于0和列表大小之间的随机数x
,将数字放在列表中的索引x
,然后将其从列表中删除。
重复上一步5次。 而且你已经完成了。 请注意, java.util.Random
有一个nextInt(int max)
方法,您应该使用它而不是Math.random()
。
关于性能的注意事项:与“尝试直到获得6个不同数字”的各种解决方案相比,此解决方案具有优势:它在O(n)时间内运行。 对于50个中的6个唯一数字来说并不重要,但是如果你想从50个中获得48或49个独特的随机数,你将开始看到差异,因为你可能必须在得到一个之前生成许多随机数那个尚未出现在集合中。
编辑:
为了减少删除列表中元素所引起的成本,您可以简单地将索引x
处的元素替换为列表的最后一个元素(在第二次迭代中,元素大小为2,等等)
您可以使用Set
。
Set s = new HashSet<>(); while(s.size() != 6){ s.add(1 + (int) (Math.random() * 49)); } Integer[] arr = s.toArray(new Integer[s.size()]);
这足以在您的情况下执行此操作,因为与您生成它们的范围的大小相比,不同随机数的数量相对较小。
否则我会采用@JBNizet方法。
生成任意6个数字(不一定不同)。 订购它们。
a1 <= a2 <= a3 <= a4 <= a5 <= a6
现在拿这6个号码
a1 这6个是不同的和随机的。 这种结构的想法来自一些组合certificate。 它的优点是简单,快速和确定。
我认为时间复杂度是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
您可以在生成数字时使用更多智能,而不是检查数组是否没有重复项,这样就可以在一开始就强制执行唯一性。
- 只要您的范围(49个条目),创建一个
boolean[]
; - 从全范围生成一个随机数;
- 把那个数字放到你的输出数组中;
- “交叉”
boolean[]
的相应索引; - 现在生成另一个随机数,但缩小范围一个(现在为48);
- 而不是直接使用该数字作为输出,扫描您的
boolean[]
,计算所有非交叉条目。 当您达到等于步骤5中生成的随机数的计数时停止。与该条目对应的数字是您的输出数字; - 转到第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; }
我刚刚提出了一个关于Java 8的小想法。
Set set = new LinkedHashSet<>(); while(set.size() != 6) set.add(rnd.nextInt(49) + 1);
只要它们是唯一的,只需保持生成数字并将它们添加到数组中; 伪代码:
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
一个设置为以此方式生成的编号。
您将得到一个有序的列表,其中包含6个随机数,范围为1..49,没有重复。
该代码生成1000到100000之间的数字并保存在ArrayList中。
如果生成的数字重复,则程序再次生成数字。 如果生成的数字不同,则添加该数字。
码:
private ArrayList arraylist = new ArrayList (); private Random rand = new Random(); public void insertNumber() { while (true) { int i = generateNumber(); if(!isGenerateNumberExists(i)){ addNumber(i); break; } } } private int generateNumber() { return rand.nextInt(100000) + 1000; } private boolean isGenerateNumberExists(int y) { for (int num : arraylist) { if (num == y) { return true; } } return false; } private void addNumber(int x) { arraylist.add(x); }