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

我正在编写一个PHP脚本,它基本上是一个礼物抓取包(从帽子里拿出名字)。但有几个条件:
-您不能与您的配偶配对
-你不可能拥有去年拥有的人
-你不能拥有你自己(显然)

我给类似的人写了一段代码:

// 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>";