【问题标题】:All combinations of 2D array with mutual exclusivity具有互斥性的二维数组的所有组合
【发布时间】:2014-06-07 11:49:49
【问题描述】:

我有一个如下所示的数组:

$i[0] = ['a', 'b', 'c'];
$i[1] = ['d', 'e'];
$i[2] = ['a', 'b', 'c'];
$i[3] = ['d', 'e'];
$i[4] = ['f', 'g', 'h'];

我想获得这个数组的所有可能的排列或组合,但不要从两个或多个子数组中两次使用相同的值。例如,结果a d b e f 是可能的,但不是a d a d f

我已经尝试过基本的置换算法,但我不知道如何修改它来做我想做的事情。

这是我目前所拥有的:

function array_permutation(array $a){
    $count = array_map('count', $a);
    $finalSize = 1;

    foreach ($count as $val) {
        $finalSize *= $val;
    }

    $output = [];

    for ($i = 0; $i < $finalSize; $i++) {
        $output[$i] = [];
        for ($c = 0; $c < count($a); $c++) {
            $index = ($i + $finalSize) % $count[$c];
            array_push($output[$i], $a[$c][$index]);
        }
    }
    return $output;
}

【问题讨论】:

  • $i[0],$i[1] 每个又是一个数组,对吧?
  • 是的,$i 的子数组。
  • 你有没有检查过重复的组合总数是多少?
  • 重复值是 108。
  • 最简单的方法是计算笛卡尔积并删除具有重复项的条目。查找array_cartesian

标签: php algorithm combinations permutation mutual-exclusion


【解决方案1】:

一个非常简单的方法是普通循环:

function decartProductExclusive($one, $two)
{
   $result = [];
   for($i=0; $i<count($one); $i++)
   {
      for($j=0; $j<count($two); $j++)
      {
         if(!count(array_intersect((array)$one[$i], (array)$two[$j])))
         {
            $result[]=array_merge((array)$one[$i], (array)$two[$j]);
         }
      }
   }
   return $result;
}

function createAssociation()
{
   $args   = func_get_args();
   if(!count($args))
   {
      return [];
   }
   $result = array_shift($args);
   while($array=array_shift($args))
   {
      $result=decartProductExclusive($result, $array);
   }
   return $result;
}

$i[0] = ['a', 'b', 'c'];
$i[1] = ['d', 'e'];
$i[2] = ['a', 'b', 'c'];
$i[3] = ['d', 'e'];
$i[4] = ['f', 'g', 'h'];

$result = call_user_func_array('createAssociation', $i);

(检查fiddle)您的问题是关于评估Cartesian product,但有条件,该元组不能包含重复元素。但是,可以在不评估每次迭代中的交集的情况下满足此条件(这将是一种矫枉过正)。相反,您可以使用array_unique() 过滤结果数组,就像在this fiddle 中一样。

【讨论】:

    猜你喜欢
    • 2022-01-25
    • 2018-11-25
    • 2019-04-18
    • 2012-07-04
    • 1970-01-01
    • 1970-01-01
    • 2014-06-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多