Bug in random numbers in Android

后端 未结 3 1895
我在风中等你
我在风中等你 2021-01-26 03:14
TreeSet myNumbers = new TreeSet();
Random randGen = new Random();

for (int i = 1; i <= 16; i++) {
    // number generation here
    int randNum = randGen.nextInt(16          


        
相关标签:
3条回答
  • 2021-01-26 03:34

    To generate a random number in a range, it is like:

    int min = ...
    int max = ...
    int randNumber = min + new Random().nextInt(max - min + 1);
    

    So in your example where you want to generate a random number from [1, 16], it would look like:

    int randNumber = 1 + new Random().nextInt(16 - 1 + 1);
    

    Or if you choose to simplify:

    int randNumber = 1 + new Random().nextInt(16);
    

    Also, you should really be using a while loop instead of an infinite for loop:

        final TreeSet<Integer> myNumbers = new TreeSet<>();
        final Random rand = new Random();
        for(int i = 0; i < 16; i++){
            int n = 1 + rand.nextInt(16);
            while(!myNumbers.add(n))
                n = 1 + rand.nextInt(16);
        }
    
    0 讨论(0)
  • 2021-01-26 03:43

    You're only generating one number in the range 1-15. You're then generating subsequent numbers with just nextInt:

    if (myNumbers.add(randNum))
        break;
    else
        randNum = randGen.nextInt();
    

    That should be:

    if (myNumbers.add(randNum))
        break;
    else
        randNum = randGen.nextInt(16) + 1;
    

    ... and fix the initial call to nextInt to remove the "-1". (You don't need the 16 - 1, as explained in Josh's answer.)

    0 讨论(0)
  • 2021-01-26 03:49

    It's not a big issue, if you are working in the range 1-16, but your code results in rejection of some randomly drawn numbers, if they have already been picked before. In your solution, the expected value of nextInt() calls is proportional to n log(n), where n is the number of total elements you want to shuffle (16 in your case) – and the actual values can be much higher for a single run. You might consider using a more efficient implementation.

    A solution which always uses only n calls:

    ArrayList<Integer> originalNumbers = new ArrayList<Integer>();
    Random randGen = new Random();
    int max = 16;
    for (int i = 1; i <= max; i++) {
        // initializing ordered list so it becomes 1, 2, ..., max
        originalNumbers.add(i);
    }
    for (int i = max; i >= 1; i--) {
        // picking a random number from the ordered list, and swapping it
        // with the last unpicked element which is placed closer to the
        // end of list, where the already picked numbers are stored
        int randNum = randGen.nextInt(i);
        Collections.swap(originalNumbers, i - 1, randNum);
        Toast.makeText(getApplicationContext(), "" + originalNumbers[i - 1], 100).show();
    }
    
    0 讨论(0)
提交回复
热议问题