php比较用于配对人员的数组(带条件)
我正在编写一个PHP脚本,它基本上是一个礼物抓取包(从帽子里拿出名字)。但有几个条件:php比较用于配对人员的数组(带条件),php,arrays,multidimensional-array,multiple-conditions,Php,Arrays,Multidimensional Array,Multiple Conditions,我正在编写一个PHP脚本,它基本上是一个礼物抓取包(从帽子里拿出名字)。但有几个条件: -您不能与您的配偶配对 -你不可能拥有去年拥有的人 -你不能拥有你自己(显然) 我给类似的人写了一段代码: // I'm using a multidimensional array so I can check the spouses $array = array( array('Husband1', 'Wife1'), array('Husband2', 'Wife2'), array('Hu
-您不能与您的配偶配对
-你不可能拥有去年拥有的人
-你不能拥有你自己(显然) 我给类似的人写了一段代码:
// I'm using a multidimensional array so I can check the spouses
$array = array(
array('Husband1', 'Wife1'),
array('Husband2', 'Wife2'),
array('Husbad3', 'Wife3'),
array('Single1'),
array('Single2'),
);
// if you were to sort the above array - here is their recipients lastYear
$lastYear = array(
'Single1',
'Husbad3',
'Single2',
'Wife3',
'Husband1',
'Wife2',
'Husband2',
'Wife1',
);
// declaring an empty values
$that = array();
$n = 0;
// converts multidimensional array to 2 identical arrays
for ($row = 0; $row < count($array); $row++)
{
for ($col = 0; $col < 2; $col++)
{
if (isset($array[$row][$col]))
{
$toList[] = $array[$row][$col];
$fromList[] = $array[$row][$col];
}
}
}
echo "Last Year \n";
// creates a list for last year
for ($row = 0; $row < count($toList); $row++)
{
echo $toList[$row] . " had " . $lastYear[$row] . "\n";
}
// randomly mixes up the to the toList
shuffle($toList);
echo "This Year \n";
// pairs the multidimensional array 1 index at a time
for ($row = 0; $row < count($array); $row++)
{
for ($col = 0; $col < 2; $col++)
{
// if it exists then print it out
if (isset($array[$row][$col]))
{
// if the toList index is the same person (as in $array), or already paired (in $that array), or a spouse (in $array), or the same person as last year - RESHUFFLE
while ($array[$row][$col] == $toList[$row] or in_array($toList[$row], $that) or in_array($toList[$row],$array[$row]) or $toList[$row] == $lastYear[$row])
{
// if it takes more then 200 Shuffles - BREAK
if ($n > 200)
{
echo "I'm Broke!! \n";
exit;
}
shuffle($toList);
$n++;
}
// once you find a match, add it to $that array and move on
$that[] = $toList[$row];
echo $array[$row][$col] . " has " . $toList[$row] . "\n";
}
}
}
这不是我想要的解释。但这在理论上似乎是正确的。这应该让你开始:
$lastYear = array(
"Husband1" => "Single1",
"Wife1" => "Husbad3",
"Husband2" => "Single2",
"Wife2" => "WIfe3",
"Husbad3" => "Husband1",
"Wife3" => "Wife2",
"Single1" => "Husband2",
"Single2" => "Wife1");
$spouses = array(
'Husband1' => 'Wife1',
'Husband2' => 'Wife2',
'Husbad3' => 'Wife3',
'Single1' => null,
'Single2' => null);
// Add corresponding spouses to $spouses
foreach($spouses as $key => $value)
if($value !==null)
$spouses[$value] = $key;
$thisYear = array(); // To hold this year's assignments
$tos = array(); // Temp var to hold potential assignment
$iterations=0; // Count number of times through the loop (fail after 100)
do
{
$success=true; // will set to false if anyone can't be assigned
foreach(array_keys($lastYear) as $key)
{
$thisYear[$key] = null; // null out all "to"s
$tos[] = $key; // create temp array with copy of "from" list
}
// go through each "from" person
foreach(array_keys($thisYear) as $from)
{
// shuffle the "to" array which contains remaining potential "to" people
shuffle($tos);
// start with the last item in $to[]. If it's ineligible for any reason, then we'll check the previous one, and so on
$checkTo=count($tos)-1;
do
{
$to = $tos[$checkTo];
if($to !== $from
&& $spouses[$from] !== $to
&& $lastYear[$from] !== $to)
{
// $to is an eligible assignment for $from. Add it to $thisYear, and remove it from $tos[]
$thisYear[$from] = $to;
array_splice($tos,$checkTo,1);
break;
}
} while (--$checkTo >= 0);
// if checkTo < 0, then there are no eligible assignments for $from. Set $success=false so we'll try again
if($checkTo<0)
{
$success=false;
break;
}
}
} while($success==false && $iterations++ < 100);
foreach($thisYear as $key => $value)
echo "$key is assigned to $value<br>";
$lastYear=数组(
“丈夫1”=>“单身1”,
“妻子1”=>“丈夫3”,
“丈夫2”=>“单身2”,
“妻子2”=>“妻子3”,
“丈夫3”=>“丈夫1”,
“妻子3”=>“妻子2”,
“单身1”=>“丈夫2”,
“单身2”=>“妻子1”);
$s=数组(
“丈夫1”=>“妻子1”,
“丈夫2”=>“妻子2”,
“丈夫3”=>“妻子3”,
'Single1'=>null,
'Single2'=>null);
//将相应的配偶添加到$partners
foreach($key=>$value)
如果($value!==null)
$MENTARES[$value]=$key;
$thiswear=array();//举行今年的任务
$tos=array();//保留潜在分配的临时变量
$iterations=0;//计算通过循环的次数(100次后失败)
做
{
$success=true;//如果无法分配任何人,则将设置为false
foreach(数组_键($lastYear)作为$key)
{
$thiseyear[$key]=null;//将所有“to”都清空
$tos[]=$key;//使用“发件人”列表的副本创建临时数组
}
//对每个“发件人”进行检查
foreach(数组_键($thiseyear)作为$from)
{
//洗牌“to”数组,其中包含剩余的潜在“to”人
洗牌($tos);
//从$to[]中的最后一项开始。如果由于任何原因它不合格,那么我们将检查前一项,依此类推
$checkTo=计数($tos)-1;
做
{
$to=$tos[$checkTo];
如果($to!==$from)
&&$from[$from]!==$to
&&$lastYear[$from]!==$to)
{
//$to是$from的合格分配。今年将其添加到$tos,然后将其从$tos[]中删除
$thiswear[$from]=$to;
阵列拼接($tos,$checkTo,1);
打破
}
}而(--$checkTo>=0);
//如果checkTo<0,则$from没有符合条件的分配。设置$success=false,因此我们将重试
如果($checkTo$value)
echo“$键被分配给$value
”;
这看起来像是我想被邀请参加的聚会。我现在没有时间写一个完整的答案,但while语句中的逻辑是非常错误的。你引用的是$toList[$row],尽管$row是$array的循环。我想你最好创建两个assoc数组(name->party,name->去年的“to”);这样可以更容易地查找无效的匹配项。@Joe我明白你的意思。我可以尝试用关联数组重写它。我不能创建一个新参数来替换行吗?或者这是小题大做吗?
$lastYear = array(
"Husband1" => "Single1",
"Wife1" => "Husbad3",
"Husband2" => "Single2",
"Wife2" => "WIfe3",
"Husbad3" => "Husband1",
"Wife3" => "Wife2",
"Single1" => "Husband2",
"Single2" => "Wife1");
$spouses = array(
'Husband1' => 'Wife1',
'Husband2' => 'Wife2',
'Husbad3' => 'Wife3',
'Single1' => null,
'Single2' => null);
// Add corresponding spouses to $spouses
foreach($spouses as $key => $value)
if($value !==null)
$spouses[$value] = $key;
$thisYear = array(); // To hold this year's assignments
$tos = array(); // Temp var to hold potential assignment
$iterations=0; // Count number of times through the loop (fail after 100)
do
{
$success=true; // will set to false if anyone can't be assigned
foreach(array_keys($lastYear) as $key)
{
$thisYear[$key] = null; // null out all "to"s
$tos[] = $key; // create temp array with copy of "from" list
}
// go through each "from" person
foreach(array_keys($thisYear) as $from)
{
// shuffle the "to" array which contains remaining potential "to" people
shuffle($tos);
// start with the last item in $to[]. If it's ineligible for any reason, then we'll check the previous one, and so on
$checkTo=count($tos)-1;
do
{
$to = $tos[$checkTo];
if($to !== $from
&& $spouses[$from] !== $to
&& $lastYear[$from] !== $to)
{
// $to is an eligible assignment for $from. Add it to $thisYear, and remove it from $tos[]
$thisYear[$from] = $to;
array_splice($tos,$checkTo,1);
break;
}
} while (--$checkTo >= 0);
// if checkTo < 0, then there are no eligible assignments for $from. Set $success=false so we'll try again
if($checkTo<0)
{
$success=false;
break;
}
}
} while($success==false && $iterations++ < 100);
foreach($thisYear as $key => $value)
echo "$key is assigned to $value<br>";