有一个名称数组,例如:
$ donalds_nephews = array('Huey','Dewey','Louie');
array
(
[0] => Huey
[1] => Dewey
[2] => Louie
)
我想要对这个数组进行洗牌,但要确保原始数组的值与洗牌的数据没有相同的键。
$donalds_nephews_shuffled = shuffle($donalds_nephews);
这可能导致6种可能的排列:
第1,第2,第4和第5不能是结果。
最好的方法是什么?这是秘密圣诞老人。
答案 0 :(得分:5)
随机播放原始数组,然后复制它并将所有条目移到一起,然后将两者重新匹配以获得匹配。
答案 1 :(得分:1)
这是秘密圣诞老人。
然后从更好的算法开始。目前,您似乎在推断密钥是当前的提供者,而现值接收者的价值(反之亦然)。然后需要进行额外的检查(并且可能重新进行改组)以确保没有人最终给自己送礼物。
但是,如果您只是将其视为有序的名单列表,那么每个条目都会给列表中的下一个人:
$victims=array('Huey', 'Dewey', 'Louie');
shuffle($victims);
$giver='';
foreach($victims as $receiver) {
if ($giver) print "$giver gives to $receiver\n";
$giver=$receiver;
}
$receiver=array_shift($victims);
print "$giver gives to $receiver\n";
答案 2 :(得分:1)
因为我的秘密圣诞老人需要这个:):
<?php
function compareArrays($original, $shuffled){
for($i = 0; $i < count($original); $i++ ){
if($original[$i] == $shuffled[$i]){
return false;
}
}
return true;
}
$donalds_nephews = array('Huey', 'Dewey', 'Louie','Igor','Stephan');
//avoid loops
for($j = 0; $j < 50; $j++){
$shuffled = $donalds_nephews;
shuffle($shuffled);
$good = compareArrays($donalds_nephews, $shuffled);
if($good) break;
}
if($good){
echo "here we go!\n";
foreach($shuffled as $k => $v){
echo "$k => $v \n";
}
}
else {
echo "try again \n";
}
?>
答案 3 :(得分:0)
不要试图将所有这些变成一个函数来使这变得复杂。
这是您的伪代码:
$givers = array( 'Huey', 'Dewey', 'Louie' );
$getters = $givers;
foreach ( $givers as $giver ) {
do {
pick a random $getter from $getters;
} until $getter <> $giver;
delete $getter from $getters;
print "$giver gives to $getter\n";
}
答案 4 :(得分:0)
这是一个古老的问题,但是您要求最好的方法,那么呢?
function santaYates($array) {
$returnArray = array_values($array); // Cause we need a clean numeric array
$secure = false;
for($i = count($returnArray) - 1; $i > 1; $i--) {//Countdown to 1 instead 0
$r = mt_rand(0, $i-1); //subtract 1 from $i to force a new place.
$tmp = $returnArray[$i];
$returnArray[$i] = $returnArray[$r];
$returnArray[$r] = $tmp;
}
return $returnArray;
}
它的工作原理与Fisher-Yates shuffle类似。
只有两个小区别: