簡體   English   中英

非重復隨機數數組

[英]Non repeating random number array

我需要創建一個典型的整數填充數組,其中包含10個隨機的非重復數,范圍是0到20。此外,我需要能夠對其進行修改,以便排除一些0到20之間的隨機數。

我怎樣才能做到這一點?

您可以通過三個簡單的步驟完成此操作:

  1. 用所需的所有候選號碼建立清單
  2. 使用Collections.shuffle隨機播放列表
  3. 使用該隨機排列的列表的前n個元素。

首先建立一個大小為20且值為0,...,19
然后shuffle()
最后-獲取包含前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<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;
}

怎樣制作一個最多由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++;
}

這樣,它應該只循環十次,但是我可能是錯的。 希望能幫助到你

編輯:並且為了修改它以排除某些數字,您將只需要一個方法,該方法將包含所述數字的數組作為參數,並遍歷整個數組,從中刪除每個數字,然后生成隨機數。

其他大多數響應都提供了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數組中隨機選擇一個數字。 然后,將其從陣列中刪除。 然后刪除數組末尾的數字,並將其放置在我們要返回的數字的位置。 這樣可以確保我們已放置所有兩個條件。

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

就是這樣!

好吧,我忍不住不發布我的解決方案,該解決方案是先將數字序列存儲到兩倍的隨機位置中。 然后將其壓縮到結果數組中。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM