PHP数组组合

NVG*_*NVG 25 php arrays combinations

我有一个7个数字(1,2,3,4,5,6,7)的数组,我想要成对的5个数字,如(1,2,3,4,5),(1,2,3) ,4,6,),(1,2,3,4,7).(1,2,3,4,5)等于(4,5,3,1,2)

我想知道PHP或任何算法中是否有函数可以执行此操作?我不知道从哪里开始.你能帮助我吗 ?

我希望将7个给定数字(它们从一个数组中取出)的所有组合放入5个插槽中,无视顺序

Gal*_*len 36

您可以使用此处找到的解决方案http://stereofrog.com/blok/on/070910.

如果链接在这里是代码....

class Combinations implements Iterator
{
    protected $c = null;
    protected $s = null;
    protected $n = 0;
    protected $k = 0;
    protected $pos = 0;

    function __construct($s, $k) {
        if(is_array($s)) {
            $this->s = array_values($s);
            $this->n = count($this->s);
        } else {
            $this->s = (string) $s;
            $this->n = strlen($this->s);
        }
        $this->k = $k;
        $this->rewind();
    }
    function key() {
        return $this->pos;
    }
    function current() {
        $r = array();
        for($i = 0; $i < $this->k; $i++)
            $r[] = $this->s[$this->c[$i]];
        return is_array($this->s) ? $r : implode('', $r);
    }
    function next() {
        if($this->_next())
            $this->pos++;
        else
            $this->pos = -1;
    }
    function rewind() {
        $this->c = range(0, $this->k);
        $this->pos = 0;
    }
    function valid() {
        return $this->pos >= 0;
    }

    protected function _next() {
        $i = $this->k - 1;
        while ($i >= 0 && $this->c[$i] == $this->n - $this->k + $i)
            $i--;
        if($i < 0)
            return false;
        $this->c[$i]++;
        while($i++ < $this->k - 1)
            $this->c[$i] = $this->c[$i - 1] + 1;
        return true;
    }
}


foreach(new Combinations("1234567", 5) as $substring)
    echo $substring, ' ';
Run Code Online (Sandbox Code Playgroud)

12345 12346 12347 12356 12357 12367 12456 12457 12467 12567 13456 13457 13467 13567 14567 23456 23457 23467 23567 24567 34567

  • @devpro 组合的数量像阶乘一样增长,甚至比指数还要快。对于 50 个元素,C(50,25) = 50!/(25!x 25!) = 126,410,606,437,752。假设生成序列不需要任何成本,并且您可以在 1μs 内处理任何给定序列(每秒一百万个序列),那么您将需要大约四年的时间来处理 C(50,25) 序列。使用生成器可能会避免内存问题,但无论如何您都没有足够的 CPU 来对结果执行任何有用的操作。 (3认同)
  • 感谢您在此处发布此链接,因为该链接现在似乎已失效:) (2认同)

小智 13

<?php

echo "<pre>";
$test = array("test_1","test_2","test_3");

// Get Combination
$return = uniqueCombination($test);

//Sort
sort($return);

//Pretty Print
print_r(array_map(function($v){ return implode(",", $v); }, $return));

function uniqueCombination($in, $minLength = 1, $max = 2000) {
    $count = count($in);
    $members = pow(2, $count);
    $return = array();
    for($i = 0; $i < $members; $i ++) {
        $b = sprintf("%0" . $count . "b", $i);
        $out = array();
        for($j = 0; $j < $count; $j ++) {
            $b{$j} == '1' and $out[] = $in[$j];
        }

        count($out) >= $minLength && count($out) <= $max and $return[] = $out;
        }
    return $return;
}

?>
Run Code Online (Sandbox Code Playgroud)

产量

Array
(
    [0] => test_1
    [1] => test_2
    [2] => test_3
    [3] => test_1,test_2
    [4] => test_1,test_3
    [5] => test_2,test_3
    [6] => test_1,test_2,test_3
)
Run Code Online (Sandbox Code Playgroud)

  • 还有我的!但对其工作原理的解释确实会有帮助!...尤其是那些 `sprintf()` 和 `and` 用法 (2认同)

Sal*_*n A 10

Math_Combinatorics在PEAR库不正是你想要什么:

一个包,返回给定集和子集大小的所有组合和排列,无需重复.保留关联数组.

require_once 'Math/Combinatorics.php';
$combinatorics = new Math_Combinatorics;

$input = array(1, 2, 3, 4, 5, 6, 7);
$output = $combinatorics->combinations($input, 5); // 5 is the subset size

// 1,2,3,4,5
// 1,2,3,4,6
// 1,2,3,4,7
// 1,2,3,5,6
// 1,2,3,5,7
// 1,2,3,6,7
// 1,2,4,5,6
// 1,2,4,5,7
// 1,2,4,6,7
// 1,2,5,6,7
// 1,3,4,5,6
// 1,3,4,5,7
// 1,3,4,6,7
// 1,3,5,6,7
// 1,4,5,6,7
// 2,3,4,5,6
// 2,3,4,5,7
// 2,3,4,6,7
// 2,3,5,6,7
// 2,4,5,6,7
// 3,4,5,6,7
Run Code Online (Sandbox Code Playgroud)