【问题标题】:PHP: Using too many nested loops, looking for a more efficient solutionPHP:使用太多嵌套循环,寻找更高效的解决方案
【发布时间】:2025-12-18 09:30:01
【问题描述】:

我的脚本以数组 $givenNumbers 为中心,随机数从 1 到 1000:

$givenNumbers = [383, 886, 777, 84, 327, 336, 505, 846, 729, 313, 857, 124, 895, 582, 545, 814, 367, 434, 364, 43, 750, 87, 808, 276, 178, 788, 584, 403, 651, 754, 399, 932, 60, 676, 368, 739, 12, 226, 586, 94, 539, 654, 999, 5, 24];

对数组进行排序并删除所有重复的元素:

 $givenNumbers = array_unique($givenNumbers);
 sort($givenNumbers);

然后我声明变量$amount,它是$givenNumbers中元素的数量;

$amount = count($givenNumbers);

我现在使用循环将数组的所有可能切片存储在数组 $slices 中:

$slices = [];
for ($i = 0; $i < $amount; $i++) {
        for($j = 0; $j < $amount; $j++) {
            array_push($slices, array_slice($givenNumbers, $i, $j));
        }
    }

将所有切片存储在$slices 中后,我想找到十个切片的所有可能组合,如果它们合并在一起,将包含$givenNumbers 的所有元素,而没有任何元素出现两次或更多次。

我试图通过循环slices 的键来做到这一点:

$combinations[]
for($i = 0; $i < $amount; $i++) {
        for($j = $i+1; $j < $amount; $j++) {   
            for($k = $j+1; $k < $amount; $k++) {
                for($l = $k+1; $l < $amount; $l++) {
                    for($m = $l+1; $m < $amount; $m++) {
                        for($n = $m+1; $n < $amount; $n++) {   
                            for($o = $n+1; $o < $amount; $o++) {
                                for($p = $o+1; $p < $amount; $p++) {
                                    for($q = $p+1; $q < $amount; $q++) {
                                        for($r = $q+1; $r < $amount; $r++) {

                                            $combStorer = [];
                                            $placeholder = array_merge($slices[$i], $slices[$j], $slices[$k], $slices[$l], $slices[$m], $slices[$n], $slices[$o], $slices[$p], $slices[$q], $slices[$r]);
                                            $placeholder = array_unique($placeholder);
                                            if (count($placeholder) == $amount) {
                                                    array_push($placeholder, $slices[$i], $slices[$j], $slices[$k], $slices[$l], $slices[$m], $slices[$n], $slices[$o], $slices[$p], $slices[$q], $slices[$r]);
                                                    foreach ($placeholder as $comb) {
                                                    $combStorer[] = $comb;
                                                }
                                                $combinations[] = $combStorer;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }

这应该基本上找到slices中符合我要求的十个数组的所有组合,并将它们以多维数组的形式存储在$combinations中。

但是,当我打开实时预览时,我收到一个致命错误,因为已超过 30 秒的最长执行时间。

一些用户提请我注意,这种方法过于复杂,肯定有更好的解决方案。

谁能提出更有效的解决方案?

【问题讨论】:

  • 我什至不想知道这一切的目的是什么。
  • 是什么让你说循环必须是无限的?内部循环将运行的次数等于 $amount 的 10 次方。即使 $amount 只是 2,也就是 1024 次。如果$amount 为 3,它将运行 59,049 次。对于更大的值,这将大大增加。因此,您的脚本超时也就不足为奇了,而删除几个循环(因此它只运行 n^8 次而不是 n^10 次)会产生巨大的差异,这一点也不奇怪。您需要找到一种更有效的方法来做您正在尝试的任何事情。
  • 循环可能不是无限的,而是足够长到大于 30 秒。减少$amount 并检查。
  • 提供$amount 值。另外,尝试增加执行时间。
  • 你想用这个解决什么问题?

标签: php performance loops for-loop nested-loops


【解决方案1】:

不是无限的,只是非常 非常大量的迭代,基本上:

(amount ^ 10) / 2

这会以极快的速度上升,例如,对于增加 amount 的值:

$ time php index.php 5

real    0m0.067s
user    0m0.043s
sys     0m0.023s
$ time php index.php 10

real    0m0.061s
user    0m0.046s
sys     0m0.014s
$ time php index.php 15

real    0m0.117s
user    0m0.096s
sys     0m0.012s
$ time php index.php 20

real    0m0.546s
user    0m0.506s
sys     0m0.030s
$ time php index.php 25

real    0m3.245s
user    0m3.204s
sys     0m0.032s
$ time php index.php 30

real    0m24.624s
user    0m24.129s
sys     0m0.032s
$ time php index.php 35

real    1m55.215s
user    1m54.532s
sys     0m0.029s

【讨论】: