4

我正在尝试遍历二维数组并自动获取列组合的总和。

假设我有一个名为 $a 的数组,它有 4 列:0、1、2、3,

$a=array();
$a[0][0]=1;
$a[0][1]=3;
$a[0][2]=5;

$a[1][0]=10;
$a[1][1]=2;  
$a[1][2]=5;
$a[1][3]=7;

$a[2][0]=9;
$a[2][1]=8;  
$a[2][2]=9;
$a[2][3]=8;

$a[3][0]=9;
$a[3][1]=8;  
$a[3][2]=9;
$a[3][3]=8;
$a[3][4]=1;

我正在尝试使用此代码对 sum(0,0;1,0;2;0,3;0) 等列的所有组合求和

for($i=0;$i<count($a[0]);$i++){
for($l=0;$l<count($a[1]);$l++){ 
for($s=0;$s<count($a[2]);$s++){ 
for($m=0;$m<count($a[3]);$m++){
 echo $sum[]= $a[0][$i]+$a[1][$l]+$a[2][$s]+$a[3][$m]; 
 echo $sum;
  echo "<br>";
   } 
   } 
 }
 }

 ?>

并且代码有效,问题是我正在手动执行这些for循环,必须有某种方法可以通过某种方式插入列数的计数来简化它?

我尝试了类似的东西

$numberofcolumns=4; 

for($n=0;$n<$numberofcolumns;$n++){
for($i=0;$i<count($a[$n]);$i++){
for($m=0;$m<count($a[$n+1]);$m++){
echo $sums[]= $a[$n][$i]+$a[$n+1][$m];
}
}
}

但这不起作用,必须有某种方法来简化 for 循环,这样我就不必在每列中手动输入 for 循环

有人有线索吗?

4

4 回答 4

1

您可以使用RecursiveIteratorIterator

尝试

$a = array ();
$a [0] [0] = 1;
$a [0] [1] = 3;
$a [0] [2] = 5;

$a [1] [0] = 10;
$a [1] [1] = 2;
$a [1] [2] = 5;
$a [1] [3] = 7;

$a [2] [0] = 9;
$a [2] [1] = 8;
$a [2] [2] = 9;
$a [2] [3] = 8;

$a [3] [0] = 9;
$a [3] [1] = 8;
$a [3] [2] = 9;
$a [3] [3] = 8;
$a [3] [4] = 1;

$sum = 0;
$array = new RecursiveIteratorIterator ( new RecursiveArrayIterator ( $a ) );
foreach ( $array as $key => $value ) {
        $sum += $value;
}
echo $sum;

输出

 102

用于$array = new RecursiveIteratorIterator ( new RecursiveArrayIterator ( $a[1] ) );获取每个部分的总和...

于 2012-05-06T18:22:13.870 回答
1

您可以为此使用递归,或者只是直接嵌套循环,但是在使用组合或排列时,可能性的总数可能会爆炸并变成一个巨大的数字,消耗大量内存,以至于您无法运行代码。使用迭代器是用 CPU 效率换取内存效率的好方法。这是我写的一个迭代器。

class CartesianProductIterator implements Iterator {
    protected $iterators;

    function __construct(array $iters) {
        $this->iterators = $iters;
    }

    function rewind() {
        foreach ($this->iterators as $it) {
            $it->rewind();
        }
    }

    function current() {
        $values = array();
        foreach ($this->iterators as $it) {
            $values[] = $it->current();
        }
        return $values;
    }

    function key() {
        return null;
    }

    function next() {
        /*      
        loop them in reverse, but exclude first
        why? example, odometer: 55199
        you always check the rightmost digit first to see if incrementing it would roll it over and need to be "rewound" to 0, 
        which causes the digit to the left to increase as well, which may also cause it to roll over as well, and so on...
        looping in reverse operates from right column to the left.
        we dont rewind the first column because if the leftmost column is on its last element and needs to roll over
        then this iterator has reached its end, and so rewind() needs to be explicitly called 
        */
        for ($i = count($this->iterators) - 1; $i > 0; --$i) {
            $it = $this->iterators[$i];
            $it->next();
            if ($it->valid()) {
                // were done advancing because we found a column that didnt roll over
                return;
            } else {
                $it->rewind();
            }
        }

        //if execution reached here, then all of the columns have rolled over, so we must attempt to roll over the left most column
        $this->iterators[0]->next();
    }

    function valid() {
        return $this->iterators[0]->valid();
    }
}

然后将其用作

$iterators = array();
foreach ($a as $columnNumber => $values) {
    $iterators[] = new ArrayIterator($values);
}
foreach (new CartesianProductIterator($iterators) as $combo) {
    // combo has 1 value from each of the ArrayIterators we instantiated
    printf("summing %s = %d\n", join('+', $combo), array_sum($combo));
}

这是一个演示http://codepad.org/UasdgvWf

于 2012-05-06T20:49:18.670 回答
0

如果我对您的理解正确,则此功能应该可以解决问题:

<?php
function recursive_sum($arr) { 

    $sum = 0;

    foreach($arr as $value) { 
        if(is_array($value)) {
            $sum += recursive_sum($value);
        }
        else { 
            $sum += $value;
        }
    }

    return $sum;
}  
?>

只需调用recursive_sum($a)即可获取数组中所有值的总和,如下所示:

<?php
    echo recursive_sum($a);
?>    
于 2012-05-06T18:31:24.707 回答
0
<? //PHP 5.4+
$a=[];
$a[0][0]=1;
$a[0][1]=3;
$a[0][2]=5;

$a[1][0]=10;
$a[1][1]=2;  
$a[1][2]=5;
$a[1][3]=7;

$a[2][0]=9;
$a[2][1]=8;  
$a[2][2]=9;
$a[2][3]=8;

$a[3][0]=9;
$a[3][1]=8;  
$a[3][2]=9;
$a[3][3]=8;
$a[3][4]=1;

//This is downright evil, but it works.
eval(\array_reduce(
  \array_reverse(\array_keys($a)),
  static function($eval, $key){
    return "foreach(\$a[$key]as\$i$key)$eval+\$i$key";
  },
  '{echo$sum[]=0') . ';echo"$sum<br/>";}');
?>
于 2012-05-06T20:07:45.843 回答