Android中随机数的错误

时间:2014-03-21 15:58:11

标签: java android math random

TreeSet myNumbers = new TreeSet();
Random randGen = new Random();

for (int i = 1; i <= 16; i++) {
    // number generation here
    int randNum = randGen.nextInt(16 - 1) + 1;
    for (;;) {
        if (myNumbers.add(randNum))
            break;
        else
            randNum = randGen.nextInt();

    }
    Toast.makeText(getApplicationContext(), "" + randNum, 100).show();
}

我想生成1到16之间的随机数,并且不应重复相同的数字。

上面的代码给出了输出:

2, 5, 7, 9, 1, 4, 10.4109446, -448831, 98824724, 11, 13, ...

我不知道为什么它给了我1-16范围内的随机数,请帮帮我。

3 个答案:

答案 0 :(得分:6)

要生成范围内的随机数,请执行以下操作:

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

因此,在您想要从[1,16]生成随机数的示例中,它看起来像:

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

或者,如果您选择简化:

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

此外,您应该使用while循环而不是无限for循环:

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

答案 1 :(得分:6)

您只在1-15范围内生成一个号码。然后,您只需nextInt生成后续数字:

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

应该是:

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

...并修复对nextInt的初始调用以删除&#34; -1&#34;。 (你不需要16 - 1,正如Josh的回答所解释的那样。)

答案 2 :(得分:0)

这不是一个大问题,如果你在1..16范围内工作,但是你的代码会导致拒绝一些随机抽取的数字,如果它们之前已被选中的话。 在您的解决方案中,nextInt()调用的期望值与nlog(n)成比例,其中n是您要混洗的总元素数(在您的情况下为16) - 并且单个实际值可以更高跑。您可以考虑使用更有效的实现。

始终只使用n次调用的解决方案:

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 = 1; i <= max; i++) {
    // picking a random number from the ordered list, and also removing it, so it won't appear again
    int randNum = originalNumbers.remove(randGen.nextInt(originalNumbers.size()));
    Toast.makeText(getApplicationContext(), "" + randNum, 100).show();
}