用PHP进行直积计算

非递归版本

我参考了Python的实现,并重新用非递归的方法重写了它。这种写法真的很难想得到啊…

<?php

function direct_product(array ...$arrays)
{
    $result = [[]];
    foreach ($arrays as $array) {
        $tmp = [];
        foreach ($result as $x) {
            foreach ($array as $y) {
                $tmp[] = array_merge($x, [$y]);
            }
        }
        $result = $tmp;
    }
    return $result;
}

var_export(direct_product(['A', 'B', 'C'], ['a'], [1, 2]));
/*
array (
  0 => 
  array (
    0 => 'A',
    1 => 'a',
    2 => 1,
  ),
  1 => 
  array (
    0 => 'A',
    1 => 'a',
    2 => 2,
  ),
  2 => 
  array (
    0 => 'B',
    1 => 'a',
    2 => 1,
  ),
  3 => 
  array (
    0 => 'B',
    1 => 'a',
    2 => 2,
  ),
  4 => 
  array (
    0 => 'C',
    1 => 'a',
    2 => 1,
  ),
  5 => 
  array (
    0 => 'C',
    1 => 'a',
    2 => 2,
  ),
)
*/

var_export(direct_product(['A', 'B', 'C'], [], [1, 2]));
/*
array (
)
*/

var_export(direct_product());
/*
array (
  0 => 
  array (
  ),
)
*/

最后那个是否在数学上是正确的呢?

递归生成器版本

这边的话,大致上会更节省内存。

<?php

function direct_product(array ...$arrays)
{
    if (!$arrays) {
        yield [];
    } elseif ($tails = array_pop($arrays)) {
        foreach (direct_product(...$arrays) as $body) {
            foreach ($tails as $tail) {
                yield array_merge($body, [$tail]);
            }
        }
    }
}

var_export(iterator_to_array(direct_product(['A', 'B', 'C'], ['a'], [1, 2])));
/*
array (
  0 => 
  array (
    0 => 'A',
    1 => 'a',
    2 => 1,
  ),
  1 => 
  array (
    0 => 'A',
    1 => 'a',
    2 => 2,
  ),
  2 => 
  array (
    0 => 'B',
    1 => 'a',
    2 => 1,
  ),
  3 => 
  array (
    0 => 'B',
    1 => 'a',
    2 => 2,
  ),
  4 => 
  array (
    0 => 'C',
    1 => 'a',
    2 => 1,
  ),
  5 => 
  array (
    0 => 'C',
    1 => 'a',
    2 => 2,
  ),
)
*/

var_export(iterator_to_array(direct_product(['A', 'B', 'C'], [], [1, 2])));
/*
array (
)
*/

var_export(iterator_to_array(direct_product()));
/*
array (
  0 => 
  array (
  ),
)
*/