非重复随机数组
我需要制作一个典型的整数填充数组,其中包含10个从0到20的随机非重复数字。另外,我需要能够修改它,这样我就可以从0到20中排除一些随机数。
我怎样才能做到这一点?
您可以通过三个简单的步骤完成此操作:
- 使用您想要的所有候选编号构建一个列表
- 使用
Collections.shuffle
来混洗该列表 - 使用该洗牌列表的
n
第一个元素。
首先构建一个大小为20的列表,其值为0,...,19
然后洗牌()吧
最后 – 获取包含前10个元素的子列表 。
此方法适合您。 它生成从0到20的10个唯一随机数。
public static int[] getRandomArray(){ int randomCount =10; int maxRandomNumber = 21; if(randomCount >maxRandomNumber ){ /* if randomCount is greater than maxRandomNumber * it will not be possible to generate randomCount * unique numbers **/ return null; } HashMap duplicateChecker = new HashMap(); int[] arr = new int[randomCount ]; int i = 0; while(i
*编辑:使方法确定性。 并避免无限循环的机会
public static int[] getRandomArray(){ int randomCount =10; int maxRandomNumber = 21; if(randomCount >maxRandomNumber ){ /* if randomCount is greater than maxRandomNumber * it will not be possible to generate randomCount * unique numbers **/ return null; } ArrayList arrayList = new ArrayList (); // Generate an arrayList of all Integers for(int i=0;i
如何使数字的arraylist达到20,并在每个随机数字调用之后从列表中删除数字并进入数组。
例
Random r = new Random(); int[] myArray = new int[10]; ArrayList numsToChoose = new ArrayList (); int counter = 0; for(int i = 0; i < 21; i++) { numsToChoose.add(i); } while(numsToChoose.size() > 11) { myArray[counter] = numsToChoose.remove(r.nextInt(numsToChoose.size())); counter++; }
这样它应该只循环10次,但我可能错了。 希望能帮助到你
编辑:为了修改它以排除某些数字,你只需要一个方法,将一个包含所述数字作为参数的数组,并循环通过它从生成随机数之前删除arraylist中的每个数字。
大多数其他响应提供了Collections.shuffle方法作为解决方案。 另一种理论上更快的方法如下:
首先让我们构建列表:
public class RandomWithoutReplacement { private int [] allowableNumbers; private int totalRemaining; /** * @param upperbound the numbers will be in the range from 0 to upperbound (exclusive). */ public RandomWithoutReplacement ( int upperbound ) { allowableNumbers = new int[ upperbound ]; for (int i = 0; i < upperbound; i++) { allowableNumbers[i] = i; } totalRemaining = upperbound; } }
接下来让我们考虑一下当我们需要获取下一个数字时我们需要做什么。
1)当我们请求另一个号码时,必须从可用的任何一个号码中统一选择。
2)选择后,不得再次重复。
这是我们可以做的:首先,从allowableNumbers
数组中随机选择一个数字。 然后,将其从arrays中删除。 然后删除数组末尾的数字,并将其放在我们要返回的数字的位置。 这确保了我们放置的所有2个条件。
public int nextRandom () { //Get a random index int nextIndex = (int) ( Math.random() * totalRemaining ); //Get the value at that index int toReturn = allowableNumbers [ nextIndex ]; //Find the last value int lastValue = allowableNumbers [ totalRemaining - 1 ]; //Replace the one at the random index with the last one allowableNumbers[ nextIndex ] = lastValue; //Forget about the last one totalRemaining -- ; return toReturn; }
有了它,你的function几乎完成。
我想补充一些以防万一:
public boolean hasNext () { return totalRemaining > 0; }
并在实际function的开头:
public int nextRandom () { if (! hasNext() ) throw new IllegalArgumentException(); // same as before... }
那应该是它!
好吧,我无法帮助它不要发布我的解决方案,它首先将一系列数字存储到两倍的随机位置。 然后将其压缩到结果数组中。
int [] myRandomSet = generateNumbers(20,10);
…
public int[] generateNumbers(int range, int arrayLenght){ int tempArray[]; int resultArray[]; int doubleLocations; Random generator = new Random(); doubleLocations = range * 2; tempArray = new int[doubleLocations]; resultArray = new int[arrayLenght]; for (int i=1; i<=range; i++){ if (i != 5 && i != 13){ //exclude some numbers do{ r = generator.nextInt(doubleLocations); }while(tempArray[r]!=0); tempArray[r] = i; //enter the next number from the range into a random position } } int k = 0; for (int i=0; i<(doubleLocations); i++){ if(tempArray[i] != 0){ resultArray[k] = tempArray[i]; //compact temp array k++; if (k == arrayLenght) break; } } return resultArray; }