主要问题涉及两个部分。一是关于如何洗牌。另一个是关于如何为其添加随机性。
一个简单的解决方案
这可能是对主要问题的最简单答案。对于 PHP 脚本中的大多数情况,这已经足够了。但不是全部(见下文)。
function /*array*/ seedShuffle(/*one dimentional array*/ $array, /*integer*/ $seed) {
$tmp = array();
for ($rest = $count = count($array);$count>0;$count--) {
$seed %= $count;
$t = array_splice($array,$seed,1);
$tmp[] = $t[0];
$seed = $seed*$seed + $rest;
}
return $tmp;
}
上述方法可以,即使它不会为所有可能的种子数组组合产生真正的随机洗牌。但是,如果您真的希望它保持平衡,我想 PHP 不应该是您的选择。
对高级程序员更有用的解决方案
正如 André Laszlo 所说,随机化是一项棘手的工作。通常最好让专用对象处理它。我的观点是,当你编写 shuffle 函数时,你不应该为随机性而烦恼。根据您希望随机播放的随机程度,您可能有许多 PseudoRandom 对象可供选择。因此,上面的内容可能如下所示:
abstract class PseudoRandom {
protected abstract function /*integer*/ nextInt();
public function /*integer*/ randInt(/*integer*/ $limit) {
return $this->nextInt()%$limit;
}
}
function /*array*/ seedShuffle($array, /*PseudoRandom Object*/ $rnd) {
$tmp = array();
$count = count($array);
while($count>0) {
$t = array_splice($array,$rnd->randInt($count--),1);
$tmp[] = $t[0];
}
return $tmp;
}
现在,这个解决方案是我要投票的解决方案。它将随机码与随机码分开。根据您需要的随机类型,您可以将 PseudoRandom 子类化,添加所需的方法和您喜欢的公式。并且,由于同一个shuffle函数可以与许多随机算法一起使用,因此可以在不同的地方使用一种随机算法。