使用PHP中的给定数量的插槽生成数组的所有组合

时间:2013-09-01 14:46:42

标签: php arrays function combinations

我编写了下面的函数,它接受一个数组并输出它的所有组合。

$option = array("a","b","c");

function combinations($array, $number) {
    if ($number == 1) {
        foreach ($array as $k => $v1) {
            echo $v1 . "<br>";
        }
    } elseif ($number == 2) {
        foreach ($array as $k => $v1) {
            foreach ($array as $key => $v2) {
                echo $v1 . " - " . $v2 . "<br>";
            }

        }
    } elseif ($number == 3) {
        foreach ($array as $k => $v1) {
            foreach ($array as $key => $v2) {
                foreach ($array as $key => $v3) {
                    echo $v1 . " - " . $v2 . " - " . $v3 . "<br>";
                }
            }
        }
    }
}

combinations($option, 2);

输出是:

a - a
a - b
a - c
b - a
b - b
b - c
c - a
c - b
c - c

它接受一个数字作为参数,并为组合返回1,2或3个插槽。但是我提前知道组合将有多少个插槽。大部分时间它可能在1到3之间,但我希望有一种方法可以重写它,以便它可以处理任意数量的插槽。

我是PHP的新手,所以我确信有一些简单的东西我不见了。如果有人能指出我正确的方向,我将非常感激。

更新

我不确定这是php string permutation的副本。如果我正确理解他们的问题,他们希望制作一个4槽组合。我可以用函数中的另一个elseif块完成这个。我正在寻找一种方法来使任意数量的插槽。如果我误解了,我道歉。

1 个答案:

答案 0 :(得分:0)

$option = array("a", "b");

function combinations($option, $number) {
    $combo = array_fill(0, $number, 0);
    $num_option = count($option);

    while (true) {
        // output the combination
        $output = array_fill(0, $number, 0);
        for ($i = 0; $i < $number; ++$i) {
            $output[$i] = $option[$combo[$i]];
        }
        echo implode(" - ", array_reverse($output)) . "<br>";

        // compute next combination
        $incpos = 0;
        while ($combo[$incpos] == $num_option-1) {
            $combo[$incpos++] = 0;
            if ($incpos >= $number) {
                // we wrapped around - end
                return;
            }
        }
        ++$combo[$incpos];
    }
}

combinations($option, 5);

此代码的工作原理是将当前组合视为具有$number个数字的基数N,其中N是$option数组中的值的数量。在每次迭代中,写出匹配数字的组合,然后将数字加1。当base-N数字回绕到零时,循环终止。

结果:

a - a - a - a - a
a - a - a - a - b
a - a - a - b - a
a - a - a - b - b
a - a - b - a - a
a - a - b - a - b
a - a - b - b - a
a - a - b - b - b
a - b - a - a - a
a - b - a - a - b
a - b - a - b - a
a - b - a - b - b
a - b - b - a - a
a - b - b - a - b
a - b - b - b - a
a - b - b - b - b
b - a - a - a - a
b - a - a - a - b
b - a - a - b - a
b - a - a - b - b
b - a - b - a - a
b - a - b - a - b
b - a - b - b - a
b - a - b - b - b
b - b - a - a - a
b - b - a - a - b
b - b - a - b - a
b - b - a - b - b
b - b - b - a - a
b - b - b - a - b
b - b - b - b - a
b - b - b - b - b