如何迭代计算该递归序列?寻求PHP或其他编程语言实现方案
搞定递归序列计算的可行方案
嘿,先帮你理清楚你定义的递归序列规则,避免代码和定义不一致:
A(0,j) = j + 1
A(i,0) = A(i-1,0)
A(i,j) = A(i-1, A(i,j-1))
先看你现有代码里的小bug:你处理A(i,0)的时候写的是$A[$c][$k] = $A[$c - 1][1];,这和你定义的A(i,0)=A(i-1,0)不符,得先修正这个点。另外,你提前预估数组长度的方式有点死板,而且这个序列增长速度快到离谱,迭代的话数组很快就不够用,用递归实现反而更贴合逻辑,也更简洁。
PHP 递归实现(最直观)
递归完全贴合你给的规则,不需要提前搞数组大小,直接按定义来:
function calculateSequence(int $i, int $j): int { // 基础情况:当i=0时,直接返回j+1 if ($i === 0) { return $j + 1; } // 当j=0时,递归调用上一行的j=0情况 if ($j === 0) { return calculateSequence($i - 1, 0); } // 先算A(i,j-1),再把结果代入A(i-1, ...) $prevStep = calculateSequence($i, $j - 1); return calculateSequence($i - 1, $prevStep); } // 测试几个例子看看 echo calculateSequence(0, 5); // 输出6,符合A(0,5)=5+1 echo calculateSequence(1, 0); // 等于A(0,0)=1 echo calculateSequence(1, 2); // 一步步算:A(1,2)=A(0,A(1,1))=A(0,A(0,A(1,0)))=A(0,A(0,1))=A(0,2)=3
PHP 迭代实现(避免递归栈溢出)
如果担心递归深度不够(比如i较大时PHP会报栈溢出),可以用迭代方式。不过要注意,这个序列增长速度快到吓人,稍微大一点的i/j值就会超出整数范围,甚至撑爆内存,所以迭代时最好加个边界判断:
function calculateSequenceIterative(int $i, int $j): int { // 先处理最基础的i=0情况 if ($i === 0) { return $j + 1; } // 用函数数组来保存每一行的计算逻辑,比二维数组更灵活 $rowFunctions = []; // 第0行的逻辑就是返回x+1 $rowFunctions[0] = fn($x) => $x + 1; // 逐行计算到第i行 for ($currentI = 1; $currentI <= $i; $currentI++) { // 先算当前行j=0的值:等于上一行j=0的结果 $rowZeroVal = $rowFunctions[$currentI - 1](0); // 定义当前行的计算函数 $rowFunctions[$currentI] = function($x) use ($rowFunctions, $currentI, $rowZeroVal) { if ($x === 0) { return $rowZeroVal; } // 先算当前行x-1的值,再代入上一行的函数 $prevVal = $rowFunctions[$currentI]($x - 1); return $rowFunctions[$currentI - 1]($prevVal); }; } return $rowFunctions[$i]($j); } // 测试一下 echo calculateSequenceIterative(2, 3);
几个要注意的点
- 这个序列的增长速度快到离谱,哪怕i=3,j=1都会得到超大的数,很快就会超出PHP的普通整数范围,要是需要处理大整数,可以用PHP的
BCMath扩展来做运算。 - 递归实现虽然简单,但当i和j较大时会触发PHP的递归深度限制,要是必须用递归,可以临时调整
ini_set('xdebug.max_nesting_level', 10000);,但不建议处理太大的参数。 - 你原来的代码里,
$A[$c][$k] = $A[$c - 1][1];是不符合你定义的A(i,0)=A(i-1,0)的,这是个关键bug,得修正哦。
内容的提问来源于stack exchange,提问作者Naruto Uzumaki
相关产品推荐
相关产品推荐

