PHP洗牌一包卡 [英] php shuffle a pack of cards
问题描述
我想使用php创建随机桥手的集合.我以为我可以将有序卡牌编码为下面的字符串$deal
(我喜欢在同时考虑大写和小写的情况下,它有52个字母).我发现了php函数str_shuffle
.因此,我认为我可以执行以下操作:
I would like to use php to create a collection of random bridge hands. I thought that I could encode an ordered pack of cards as the string $deal
below (I like it that there are 52 letters when considering both upper and lower case). I discovered the php function str_shuffle
. So I thought that I could do the following:
$pack = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$shuffledPack = str_shuffle($pack);
这给了我想要的输出.
This gives me the desired output.
我的问题是:str_shuffle
是否为每个可能的排列给出遵循均匀分布的输出?
My question is: does str_shuffle
give output that follows a uniform distribution for each and every possible permutation?
推荐答案
在内部,str_shuffle()
使用rand()
不会产生高质量的随机数,正如您在 mt_rand()
:
Internally, str_shuffle()
uses rand()
which doesn't produce good quality random numbers as you can see in this answer; if you want a better distribution, you may wish to implement Fisher-Yates yourself and pick a random source of your choice, e.g. mt_rand()
:
function my_str_shuffle($str)
{
if ($str == '') {
return $str;
}
$n_left = strlen($str);
while (--$n_left) {
$rnd_idx = mt_rand(0, $n_left);
if ($rnd_idx != $n_left) {
$tmp = $str[$n_left];
$str[$n_left] = $str[$rnd_idx];
$str[$rnd_idx] = $tmp;
}
}
return $str;
}
另请参阅我之前的答案有关找到合适的0/1随机数的信息.
See also my earlier answer on finding a suitable 0/1 randomiser.
使用 openssl_random_pseudo_bytes()
作为随机来源:
Using openssl_random_pseudo_bytes()
as your random source:
assert($n_left <= 255);
$random = openssl_random_pseudo_bytes($n_left);
while (--$n_left) {
$rnd_index = round($random[$n_left] / 255 * $n_left);
// ...
}
这篇关于PHP洗牌一包卡的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!