我有一个如下所示的数组:
$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;
}
答案 0 :(得分:2)
一个非常简单的方法是简单循环:
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小提琴中一样。