采用这个函数,它是一个有种子的 Fisher-Yates 洗牌(顺序是随机的,但在给定相同种子的情况下可以重现):
function seeded_shuffle(array &$items, $seed = false) {
$items = array_values($items);
mt_srand($seed ? $seed : time());
for ($i = count($items) - 1; $i > 0; $i--) {
$j = mt_rand(0, $i);
list($items[$i], $items[$j]) = array($items[$j], $items[$i]);
}
}
这个算法可以逆转吗?即,给定种子值和打乱后的数组,该数组是否可以“打乱”为其原始顺序?如果是这样,怎么办?
(问题出现了在这里的评论中.)
事实证明答案是肯定的,而且非常简单:
function seeded_unshuffle(array &$items, $seed) {
$items = array_values($items);
mt_srand($seed);
$indices = [];
for ($i = count($items) - 1; $i > 0; $i--) {
$indices[$i] = mt_rand(0, $i);
}
foreach (array_reverse($indices, true) as $i => $j) {
list($items[$i], $items[$j]) = [$items[$j], $items[$i]];
}
}
只需使用已知种子生成相同的随机数序列,然后反向遍历即可。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)