我正在尝试循环遍历二维数组并自动获取列组合的总和。
假设我有一个名为$ 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>";
}
}
}
}
?>
代码工作,问题是我手动做这些循环,必须有一些方法,我可以通过以某种方式插入列数的数量来简化这个?
我试过像
这样的东西$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循环
任何人都有线索?
答案 0 :(得分: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] ) );
获取每个部分的总和......
答案 1 :(得分: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));
}
答案 2 :(得分: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);
?>
答案 3 :(得分: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/>";}');
?>