在PHP中生成两个不相等的数字

9

我需要在PHP中生成两个不相等的数字。

我知道可以使用 $random1 = (rand()%9); 生成0-9之间的随机数。我想在此基础上添加些内容。

谢谢!

13个回答

51
$r = str_shuffle("0123456789");
$r1 = (int) $r[0];
$r2 = (int) $r[1];

5
哇,那真是个非常棒的解决方案。 - Ben Torell
2
虽然是确定性的解决方案,但在平均情况下,这种方法可能比已接受的方法慢。此外,它无法扩展以处理双位数。 - pieman72

24
$rnd1 = rand(0,9);
do {
  $rnd2 = rand(0,9);
} while ($rnd1 == $rnd2);

10
理论上,如果数字是真正随机的,这个循环可能会无限循环。在大多数计算机应用程序中不太可能发生,但运行时间确实是非确定性的,这可能并不理想。 - paxdiablo
幸运的是,大多数计算机使用实用而非理论随机生成器 :). 因此,这两个随机数彼此独立(除了原始约束条件)。 - Zed
@Fred,如果您想确保此代码不像建议的那样运行多年,可以设置一个计数器来计算重试次数,然后在阈值后简单地返回($rnd1 + 1)%10或其他内容。 - Zed
4
实际上,@DrJokepu,我们确实为这种情况做过计划(不一定是陨石,但绝对是服务器所在地被摧毁)。我们有一个备用站点,距离这里大约50公里。我记得有个有点多疑的人问如果两个站点都被灾难摧毁了我们该怎么办。我的回答是,对于如此大的灾难,我们会有更多的问题需要解决,而不仅仅是一些丢失的数据。 - paxdiablo
虽然系统影响确实很小,但从性能上来看,这不是最佳方法;另一方面,从内存角度来看,我的方法也不是最好的。我想这可以通过多种方式解决,最佳方法取决于你需要使用它的情况。 - ChrisR
显示剩余3条评论

9
$random1 = 4;
$random2 = 5;

1
实际上,如果它基于这里发现的漫画(http://xkcd.com/221/),那么这相当有趣。如果不是基于那个的话,我想这就不太好笑了 :-) - paxdiablo
它实际上受那个漫画的启发 :-D - overstood
我向您保证,它们都是随机生成的。 - overstood

8
$numbers = array_rand(range(0, 9), 2);

echo '<pre>';
print_r($numbers);
echo '</pre>';

8
$random1 = (rand() % 10)
$random2 = $random1 + (rand()%9)+1 

这样它们就永远不会相等(因为至少会将1添加到$random1)

如果两个数字都必须在0-9之间,您只需要使用最后一个模运算即可:

$random1 = (rand() % 10)
$random2 = ($random1 + (rand()%9)+1 ) %10 

我喜欢那个。取模运算使用得很好。 - Kobi
这会破坏标准分布 - 较小的数字比较大的数字略微更有可能出现,尽管在这种情况下可能不太明显。 - Chris Lutz
@chris:请解释一下为什么较小的数字稍微更有可能。我不明白为什么。 - Peter Parker

4
function random($min, $max) {
    $stack = range($min, $max);
    shuffle($stack); 
    $nr1 = array_pop($stack);
    $nr2 = array_pop($stack);
    return array($nr1, $nr2);
}

这可能是一个不需要数学天赋的技巧 :)

我猜 shuffle 至少是线性的,所以对于 max 来说这不太可扩展。然而,如果你需要超过 2 个不同的随机数,那么这种方法可能很有效。 - Kobi
超过2个不同的随机整数。 - Zed

2
我认为你会发现rand()%9可以得到0到8(包括0和8)之间的数字。如果你想要0到9(包括0和9),你应该使用rand()%10。我假设这是你想要的,但如果0到8是你真正想要的,你可以轻松地调整答案。
如果你想要在这个范围内生成两个数字,最简单的方法是先生成一个在此范围内的数字,然后再生成另一个比该数字小1的数字,如果它与第一个数字相同或更大,则将其加1。
这是数学上的解决方法,它是确定性的(无论如何都需要两次调用rand())。虽然不太可能,但真正的随机数生成器可能会产生一串完全相同的数字,这会使循环解决方案不明智(你可能正在使用线性生成器,所以这可能不是个问题)。
在第一次尝试中,你可以从整个范围内选择(10个数字,从0到9)。在第二次尝试中,你可以从除第一个数字外的整个范围内选择。所以,如果你的第一个数字是7,你就可以从0到8中选择一个数字,并将7映射到8,8映射到9:
$random1 = (rand() % 10);
$random2 = (rand() % 9);
if $random2 >= $random1 {
    $random2 = $random2 + 1;
}

这会在随机数之间引入太多的依赖性。例如,如果random1是5,则random2有更高的可能性是6而不是其他任何数字。 - Zed
我认为如果 $random2 >= $random1 会有更好的机会,但也许我错过了另一个边缘情况。 - Kobi
是的,@Kobi,你说得对,那就是我想说的,但现在这里已经很晚了 :-) - paxdiablo
@Zed,那是我没有正确记录下来的结果。如果像@Kobi指出的那样使用正确的语句进行映射,则概率是正确的。 - paxdiablo
@Pax - 应该是 $random2 >= $random1。现在的方式仍然是错误的,而且数字可能相等。 - Kobi

1
$r = mt_rand(0, 9);
$r2 = ($r || $r === 9) ? $r-1 : $r+1;

解释:

$r:它是从0到9的数字。

$r2:它总是从0到9,但不包括$r-1$r+1

更随机的方法是生成两个数字:

$r = mt_rand(0, 9);
$r2 = mt_rand(0, 9);
$r2 = $r!==$r2 ? $r2 : (($r || $r === 9) ? $r-1 : $r+1);

另外,如果您使用 PHP 7+,可以将 mt_rand 更改为 random_int


1

如果你只需要唯一的数字,那么从零开始,每次增加1即可获得新的数字。

如果你需要随机的唯一数字,可以将之前的数字保存在列表中,当你需要一个新的数字时,生成随机数字,直到找到一个不在列表中的数字。

如果你需要唯一标识符,可以使用内置函数uniqid


0
Alix Axel的解决方案对我来说是最直接的,也很好用。我想从一个现有的数组中获取三个随机条目,所以我使用了:
$rands = array_rand(range(0,count($otherarray)),3);

接下来,展示那些键在$rands里的条目。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接