Random.nextInt生成随机数重复率远超预期的问题咨询
问题分析与解决
1. 函数核心逻辑错误
你的generateOneThousandRandomNumbers函数存在致命问题:当生成的随机数已经在列表中时,仅打印重复提示,但仍然把重复的数添加进列表,继续递归执行。这导致最终返回的列表只要在生成过程中出现过重复,就必然包含重复值,测试用例x.size shouldBe x.distinct.size自然会失败。
正确的逻辑应该是:生成重复数时不添加,重新生成新的随机数,直到得到不重复的数再加入列表。修改后的函数示例:
private def generateOneThousandRandomNumbers(listOfNumbers: List[String] = List.empty): List[String] = { if (listOfNumbers.size == 1000) { listOfNumbers } else { val nextNumber: String = Random.nextInt(10000000).toString if (listOfNumbers.contains(nextNumber)) { println("DUPLICATE NUMBER GENERATED: " + nextNumber) // 重复时不添加,直接递归重新生成 generateOneThousandRandomNumbers(listOfNumbers) } else { // 不重复才添加到列表 generateOneThousandRandomNumbers(listOfNumbers ++ List(nextNumber)) } } }
2. 概率计算错误
你之前的概率计算完全不符合实际,这里需要用生日悖论模型来计算:
- 从1000万个数字中生成1000个随机数,出现重复的概率不能简单按
1/10000计算。 - 近似公式:重复概率 $P \approx 1 - e{-\frac{k(k-1)}{2N}}$,其中$N=107$,$k=1000$,代入后得到单次生成出现重复的概率约为4.8%。
- 十次测试中至少出现一次重复的概率为 $1 - (1-0.048)^{10} \approx 39%$,和你观察到的约50%接近(误差来自近似计算和随机数生成的实际特性)。
但要注意:如果函数逻辑正确(跳过重复数),最终返回的列表必然是1000个不重复的数,测试用例会始终通过,概率计算也就不影响测试结果了。
内容的提问来源于stack exchange,提问作者Edward
相关产品推荐
相关产品推荐

