如何防止重叠的随机数
我如何防止从随机数重复数字。 我需要在1到9之间生成5个不同的数字。 我经常会得到像23334这样的数字,我该如何防止? 任何帮助都会很棒!
int num2 = (int) Math.round((Math.random()*9) +1); int num1 = (int) Math.round((Math.random()*9) +1); int num5 = (int) Math.round((Math.random()*9) +1); int num3 = (int) Math.round((Math.random()*9) +1); int num4 = (int) Math.round((Math.random()*9) +1);
一种选择是使用shuffle算法(例如Fisher-Yates shuffle )生成从1到9的随机序列,然后获取序列的前5个数字
有关StackOverflow的进一步说明: https ://stackoverflow.com/a/196065/950427
Set set=new HashSet<>(); while (set.size()<5) { set.add( Math.round((Math.random()*9) +1)); }
设置完成后,您有5个唯一的随机数。
更新:只是为了说明Jared Burrows的评论
- 创建列表包括您想要的数字(1到9)。
- 生成从0到(列表大小减1)的随机数。
-
从上面生成的随机数中删除索引中的一个元素。 并将删除的元素添加到要作为结果返回的数组中
public static void main(String[] args) { int []answers= returnRandomNonRepeatingNumbers(5,0,9); for(int answer: answers) { System.out.println(answer); } } public static int[] returnRandomNonRepeatingNumbers(int sizeYouWant, int poolStart, int poolEnd) { List
pool=new ArrayList (); for(int i=poolStart;i<=poolEnd;i++) { pool.add(i); } int []answers=new int[sizeYouWant]; for(int i=0;i
如果可能的随机值数量很小,则需要使用shuffle。
List values = IntStream.range(0, 10).boxed().collect(toList()); Collections.shuffle(values); values = values.subList(0, 5);
如果可能的随机值的数量很大,您想测试将它们添加到Set(或原始列表,如果足够小)
Set valueSet = new HashSet<>(); Random rand = new Random(); while(valuesSet.size() < 5) valuesSet.add(rand.nextInt(9) + 1); List values = new ArrayList<>(valueSet); Collections.shuffle(values, rand);
注意:您需要随机播放该集合,因为它不会保留顺序。 例如,数字1,2,3将始终以HashSet的顺序出现,而不是3,2,1。
Floyd的子集选择算法旨在完全按照您的要求进行,即使对于大型集合也非常有效。 从一组n
选择m
项是O(m)
平均运行时间,与n
无关。 这是一个Java实现。
/* * Floyd's algorithm to chose a random subset of m integers * from a set of n, zero-based. */ public static HashSet generateMfromN(int m, int n) { HashSet s = new HashSet (); for (int j = nm; j < n; ++j) { if(! s.add((int)((j+1) * Math.random()))) { s.add(j); } } return s; }
解决这个问题的一种可能方法是分而治之。 以下步骤描述了该方法:
- 假设m是最小值, n是最大值,在我想得到x个数量的randoms之内
- 在m & n之间选择一个随机p 。 将其保存到答案数组中。 当我们得到一个问题的答案时,将x减少1 。
- 现在在m & p-1之间取一个q随机数,另一个r是p + 1和n之间的随机数。 填充答案数组, q和r减少x 1为q ,另一个为r 。
- 现在递归地继续该过程,直到下限( m )和上限( n )变得相等或x变为0 。
好处:这种方法的好处是,在最坏的情况下,它的运行时间为O( x ),其中x是所需的随机数。 最好的情况也是o( x ),因为我必须找到至少n个随机数。 这两个包括平均情况到θ( x )复杂度。
import java.util.Random; class GenerateDistinctRandom{ static int alreadyPut = 0; static Random rand = new Random(); public static int[] generateDistinctRandom(int howMany, int rangeMin, int rangeMax) { int randomNumbers[] = new int[howMany]; GenerateDistinctRandom.recursiveRandomGenerator(rangeMin, rangeMax, randomNumbers, howMany); return randomNumbers; } private static void recursiveRandomGenerator(int rangeMin, int rangeMax, int[] storage ,int storageSize) { if(rangeMax - rangeMin <= 0 || GenerateDistinctRandom.alreadyPut == storageSize) { return ; } int randomNumber = GenerateDistinctRandom.rand.nextInt(rangeMax-rangeMin) + rangeMin; storage[GenerateDistinctRandom.alreadyPut] = randomNumber; GenerateDistinctRandom.alreadyPut++; //calling the left side of the recursion recursiveRandomGenerator(rangeMin, randomNumber - 1, storage, storageSize); recursiveRandomGenerator(randomNumber + 1, rangeMax, storage, storageSize); } public static void main(String []args){ int howMany = 5; int distinctNumber[] = GenerateDistinctRandom.generateDistinctRandom(howMany 0, 9); for(int i = 0;i < howMany;i++) { System.out.println(distinctNumber[i]); } } }
我想你需要将已生成的数据存储到数组中,并将新的随机数与列表进行比较,以确保它是唯一的。
public static void main (String[] args) throws java.lang.Exception { // your code goes here int[] numbers = new int[5]; int tempNumber = 0; for(int numberCounter = 0; numberCounter < numbers.length;) { tempNumber = (int) Math.round((Math.random()*9) +1); if(!contains(numbers, tempNumber)){ numbers[numberCounter++] = tempNumber; } } } public static boolean contains(final int[] numbersArray, final int tempNumber) { for (final int numberFromArray : numbersArray) { if (numberFromArray == tempNumber) { return true; } } return false; }
我注意到你的例子中没有使用数组,所以如果你还不知道如何使用它们,你也可以制作5个变量。
int randomNumber = 0; int firstNumber = Math.round((Math.random()*9) +1); int secondNumber = 0; while(secondNumber == 0){ randomNumber = Math.round((Math.random()*9) +1)l if(randomNumber != firstNumber){ secondNumber = randomNumber; } }
而你可以继续做这样的陈述。 但是如果你应该知道数组,你肯定应该用一个来存储数字。
这个怎么样?
package com.se; import java.util.ArrayList; import java.util.List; import java.util.Random; public class TestRandom { List comp = new ArrayList<>(); int listSize = 20; public void doTask() { Random ran = new Random(); int i = 0; while(i < listSize){ int randomNumber = ran.nextInt(80) + 1; if(!comp.contains(randomNumber)){ comp.add(randomNumber); i++; } } for(Integer num : comp){ System.out.println(num); } } public static void main(String[] args) { TestRandom testRandom = new TestRandom(); testRandom.doTask(); } }