Java Android中的随机数Bug

Java Android中的随机数Bug,java,android,math,random,Java,Android,Math,Random,我不知道为什么它会给我不在1-16范围内的随机数,请帮助我。要生成一个范围内的随机数,如下所示: 2, 5, 7, 9, 1, 4, 10.4109446, -448831, 98824724, 11, 13, ... 因此,在您的示例中,您希望从[1,16]生成一个随机数,它看起来像: int min = ... int max = ... int randNumber = min + new Random().nextInt(max - min + 1); 或者,如果您选择简化: int

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

要生成一个范围内的随机数,如下所示:

2, 5, 7, 9, 1, 4, 10.4109446, -448831, 98824724, 11, 13, ...
因此,在您的示例中,您希望从[1,16]生成一个随机数,它看起来像:

int min = ...
int max = ...
int randNumber = min + new Random().nextInt(max - min + 1);
或者,如果您选择简化:

int randNumber = 1 + new Random().nextInt(16 - 1 + 1);
此外,您应该真正使用
while
循环,而不是无限
for
循环:

int randNumber = 1 + new Random().nextInt(16);
final TreeSet myNumbers=new TreeSet();
最终随机数=新随机数();
对于(int i=0;i<16;i++){
整数n=1+下一次随机数(16);
而(!myNumbers.add(n))
n=1+兰德·耐克斯汀(16);
}
您只生成1-15范围内的一个数字。然后,您只需使用
nextInt
,即可生成后续编号:

    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);
    }
这应该是:

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

。。。并修复对
nextInt
的初始调用以删除“-1”。(正如Josh在回答中所解释的,您不需要
16-1

如果您在1-16范围内工作,这不是一个大问题,但是您的代码会拒绝一些随机抽取的数字,如果它们以前已经被选取过。 在您的解决方案中,
nextInt()
调用的预期值与n log(n)成比例,其中n是您要洗牌的元素总数(在您的情况下为16个)–而实际值在一次运行中可能会高得多。您可能会考虑使用更有效的实现。

始终仅使用n个调用的解决方案:

ArrayList originalNumbers=new ArrayList();
Random randGen=新的Random();
int max=16;
对于(int i=1;i=1;i--){
//从有序列表中选择一个随机数,并交换它
//最后一个未拾取的元素放置在靠近
//列表末尾,存储已拾取的编号的位置
int randNum=randGen.nextInt(i);
集合.交换(原始编号,i-1,randNum);
makeText(getApplicationContext(),“”+originalNumber[i-1],100).show();
}

您的代码似乎给出了非整数结果,这表明您可能没有正确地诊断它。如果你真的能说服Android将10.4109446存储在
int
@Vyger无限空间中,我会感到惊讶loop@blackbelt:like
while(true){
?@Vyger遵循这个链接,我认为输出中的“.”只是一个输入错误,实际上是一个“,”。有可能吗?@VikrantAlekar如果它解决了你的问题,你为什么不接受它呢;以及对
Set的调用数。将
添加为O(n log n)。然后OP方法的复杂性为O((n log n)^2)。使用
HashSet
boolean[n]
会给我们带来复杂性O(n log n)。您的方法(天真的Fisher-Yates shuffle)需要O(n)时间来调用
ArrayList。删除
‒O(n^2)总数;比O(n log n)更糟。Knuth shuffle,在移除之前将所选元素与最后一个元素交换,其复杂性为O(n)。令人惊讶的是,这里没有一个答案使用它。你没有再次交换elementsthanks@kyrill,希望现在一切都好。不幸的是,我目前没有设置任何开发环境,只是盲目地编码。如果仍然不好,请告诉我。
Collections.swap(originalnumber,I-1,randNum);
因此您允许元素保持在相同的位置
if (myNumbers.add(randNum))
    break;
else
    randNum = randGen.nextInt();
if (myNumbers.add(randNum))
    break;
else
    randNum = randGen.nextInt(16) + 1;
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();
}