PHP 嵌套数组组合/排列

标签 php arrays combinations permutation combinatorics

我认为我的问题已经使用 this solution 解决了,使用 VolkerK 的答案,但它似乎无法正常工作。

我想要的是一个函数,它返回嵌套数组中包含的值的所有可能组合。

比如我传入

[ ['a', 'b'], ['a', 'b'], ['a', 'b'], ['a'], ['a'], [ 'a'] ]

它会回来

a, a, a, a, a, a
b, b, b, a, a, a
a, a, b, a, a, a
a, b, a, a, a, a
b, a, a, a, a, a
a, b, b, a, a, a
b, b, a, a, a, a
b, a, b, a, a, a

如下使用 VolkerK 的答案的问题在于它只是返回

a, a, a, a, a, a
b, b, b, a, a, a
a, a, a, a, a, a
b, b, b, a, a, a
a, a, a, a, a, a
b, b, b, a, a, a
a, a, a, a, a, a
b, b, b, a, a, a

如何修复以下代码以返回我在上面所做的正确组合? (或者您可以编写一个执行上述操作的新函数吗?)

<?php
class PermArray implements  ArrayAccess {
    // todo: constraints and error handling - it's just an example
    protected $source;
    protected $size;

    public function __construct($source) {
        $this->source = $source;
        $this->size = 1;
        foreach ( $source as $a ) {
            $this->size *= count($a);
        }
    }
    public function count() { return $this->size; }

    public function offsetExists($offset) { return is_int($offset) && $offset < $this->size; }
    public function offsetGet($offset) {
        $rv = array();
        for ($c = 0; $c < count($this->source); $c++) {
          $index = ($offset + $this->size) % count($this->source[$c]);
          $rv[] = $this->source[$c][$index];
        }
        return $rv;
    }

    public function offsetSet($offset, $value ){}
    public function offsetUnset($offset){}
}

$pa = new PermArray( [['x'], ['y', 'z', 'w'], ['m', 'n']] );
$cnt = $pa->count();
for($i=0; $i<$cnt; $i++) {
    echo join(', ', $pa[$i]), "\n";
}

最佳答案

这是一个非常“直截了当”、不优雅(如果你愿意的话也可以说是丑陋)的解决方案,并且不符合你的预期顺序(如果你关心的话):

function P(array $sources)
{
    $result=array();
    $cache=array();
    foreach($sources as $node)
    {
        $cache=$result;
        $result=array();
        foreach($node as $item)
        {
            if(empty($cache))
            {
                $result[]=array($item);
            }
            else
            {
                foreach($cache as $line)
                {
                    $line[]=$item;
                    $result[]=$line;
                }
            }
        }
    }
    return $result;
}
$result=P(array(array('a','b'),array('a','b'),array('a','b'),array('a'),array('a'),array('a')));
print_r(array_map(function($a){return implode(",",$a);},$result));

Live demo

输出:

Array
(
    [0] => a,a,a,a,a,a
    [1] => b,a,a,a,a,a
    [2] => a,b,a,a,a,a
    [3] => b,b,a,a,a,a
    [4] => a,a,b,a,a,a
    [5] => b,a,b,a,a,a
    [6] => a,b,b,a,a,a
    [7] => b,b,b,a,a,a
)

我将您的 [] 语法更改为 array() 以提供更多的向后兼容性(但匿名函数需要 PHP 5.3)。

关于PHP 嵌套数组组合/排列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19853989/

相关文章:

python - 查找 numpy 数组中第 n 次超出特定值的情况

java - 如何将 14 位二进制补码值转换为 Integer 或 Short 并在 Java 中维护符号

java - 从多个列表生成所有组合

c# - 从 n 中获取 k 元素的所有组合的算法

python - 如何对python中的所有组合进行排序?

php - 如何访问 Carbon 对象类型?

php - 使用php返回大于某个ID的所有结果

php - MYSQL Reset Auto Increment 提高性能

javascript - 在 Javascript 中将数组元素移动到顶层的推荐方法

php - PHP 如何索引关联数组?