Non repeating random number array

前端 未结 6 1918
攒了一身酷
攒了一身酷 2020-12-21 20:49

I need to make a typical integer filled array with 10 random non repeating numbers from 0 to 20. Also, I need to be able to modify this so I can exclude some random numbers

相关标签:
6条回答
  • 2020-12-21 20:59

    Well, I could't help it not to post my solution which is storing a sequance of numbers into twice as many random locations first. Then compacts it into the resultting array.

    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;
    }
    
    0 讨论(0)
  • You can do this in three easy steps:

    1. Build a list with all the candidate numbers you want
    2. Use Collections.shuffle to shuffle that list
    3. Use the n first elements of that shuffled list.
    0 讨论(0)
  • 2020-12-21 21:12

    First build a list of size 20 with values 0,...,19
    Then shuffle() it
    And last - take the sublist containing first 10 elements.

    0 讨论(0)
  • 2020-12-21 21:18

    This Method will work for you. It generate 10 unique random numbers from 0 to 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;
    }
    

    * Edited: To make the method deterministic. And Avoid the chance of infinite loop

    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;
    }
    
    0 讨论(0)
  • 2020-12-21 21:18

    Most of the other responses offer the Collections.shuffle method as a solution. Another way, which is theoretically faster is the following:

    First lets build the list:

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

    Next lets consider what we need to do when we need to get the next number.

    1) When we request another number, it must be chosen from any one of the available, uniformly.

    2) Once it is chosen, it must not repeat again.

    Here is what we can do: First, choose a number at random from the allowableNumbers array. Then, remove it from the array. Then remove the number at the end of the array, and place it in the position of the number we are to return. This ensures all of the 2 conditions we have placed.

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

    With that, your function is almost complete.

    I would add a couple more things just in case:

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

    And at the beginning of the actual function:

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

    That should be it!

    0 讨论(0)
  • 2020-12-21 21:19

    What about making an arraylist of numbers upto 20, and after each random number call you remove the number from the list and into the array.

    example

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

    That way it should only loop 10 times, I may be wrong though. Hope it helps

    EDIT: And in order to modify this to exclude certain numbers, you would just need a method that takes an array that contains said numbers as a parameter, and loop through it removing each number from the arraylist before you generate your random numbers.

    0 讨论(0)
提交回复
热议问题