非重复随机数组

时间:2012-01-29 10:37:39

标签: java

我需要制作一个典型的整数填充数组,其中包含10个从0到20的随机非重复数字。另外,我需要能够修改它,这样我就可以从0到20中排除一些随机数。

我该怎么做?

6 个答案:

答案 0 :(得分:15)

您可以通过三个简单的步骤完成此操作:

  1. 使用您想要的所有候选编号构建一个列表
  2. 使用Collections.shuffle随机播放该列表
  3. 使用该随机列表的n个第一个元素。

答案 1 :(得分:4)

首先构建一个大小为20的列表,其值为0,...,19
然后shuffle()它 最后 - 取sublist包含前10个元素。

答案 2 :(得分:4)

此方法适合您。它生成10个从0到20的唯一随机数。

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<Integer, Integer> duplicateChecker = new HashMap<Integer, Integer>();
    int[] arr = new int[randomCount ];
    int i = 0;
    while(i<randomCount ){
        // Generate random between 0-20, higher limit 21 is excluded
        int random = new Random().nextInt(maxRandomNumber );
        if(duplicateChecker.containsKey(random)==false){
            duplicateChecker.put(random, random);
            arr[i]=random;
            i++;
        }
    }
    return arr;
}

*已编辑:使方法具有确定性。并避免无限循环的机会

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<Integer> arrayList = new ArrayList<Integer>();
    // Generate an arrayList of all Integers
    for(int i=0;i<maxRandomNumber;i++){
        arrayList.add(i);
    }
    int[] arr = new int[randomCount ];
    for(int i=0;i<randomCount;i++){
        // Generate random between 0-20, higher limit 21 is excluded
        int random = new Random().nextInt(arrayList.size());
        // Remove integer from location 'random' and assign it to arr[i]
        arr[i]=arrayList.remove(random);        
    }
    return arr;
}

答案 3 :(得分:2)

如果将数字的arraylist设置为20,并且在每个随机数字调用之后,您将从列表中删除该数字并进入数组。

例如

Random r = new Random();
int[] myArray = new int[10];
ArrayList<Integer> numsToChoose = new ArrayList<Integer>();

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中的每个数字。

答案 4 :(得分:1)

大多数其他响应都提供了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数组中随机选择一个数字。 然后,将其从阵列中删除。 然后删除数组末尾的数字,并将其放在我们要返回的数字的位置。 这确保了我们放置的所有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;
      }

有了这个,你的功能几乎完成了。

为了以防万一,我会添加更多内容:

      public boolean hasNext () {
            return totalRemaining > 0;
      }

在实际功能的开头:

      public int nextRandom () {
             if (! hasNext() )
                 throw new IllegalArgumentException();
             // same as before...
      }

那应该是它!

答案 5 :(得分:0)

好吧,我无法帮助它不要发布我的解决方案,它首先将一系列数字存储到两倍的随机位置。然后将其压缩到结果数组中。

  

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;
}