递归函数countPaths的累加计算、调用流程及栈帧解析咨询
游戏棋盘路径计数代码详解:递归逻辑与栈帧分析
先看你提供的Java代码:
// Count the number of paths possible from start point to end point in game board public class CountPaths { public static void main(String[] args) { System.out.println(countPaths(0, 3)); } private static int countPaths(int sp, int ep) { if (sp == ep) { return 1; } if (sp > ep) { return 0; } int count = 0; for (int i = 1; i <= 6 ; i++) { count += countPaths(sp + i, ep); } return count; } }
一、代码核心功能
这段代码用递归模拟骰子掷出1-6点的走法,计算从起点sp到终点ep的所有合法路径数量。运行输出4,对应从0到3的路径总数。
二、递归逻辑手动推演
我们一步步拆解countPaths(0, 3)的计算过程:
- 初始调用
countPaths(0, 3):sp=0 < ep=3,初始化count=0,进入循环i=1到6:- i=1:调用
countPaths(1, 3)sp=1 < 3,初始化count=0,循环i=1到6:- i=1:调用
countPaths(2, 3)sp=2 < 3,初始化count=0,循环i=1到6:- i=1:
countPaths(3,3)→sp==ep,返回1 - i=2到6:
countPaths(4,3)、countPaths(5,3)等,sp>ep,返回0
- i=1:
- 累加后
count=1+0+0+0+0+0=1,返回1
- i=2:调用
countPaths(3,3)→ 返回1 - i=3到6:调用
countPaths(4,3)等,返回0
- i=1:调用
- 累加后
count=1+1+0+0+0+0=2,返回2
- i=2:调用
countPaths(2,3)→ 上面算过返回1,count变为2+1=3 - i=3:调用
countPaths(3,3)→ 返回1,count变为3+1=4 - i=4到6:调用
countPaths(4,3)、countPaths(5,3)、countPaths(6,3),均返回0,count保持4 - 最终返回4,和输出一致
三、栈帧结构解析
Java虚拟机(JVM)会为每个方法调用创建栈帧,递归调用时栈帧层层压入栈,方法返回后依次弹出。每个栈帧包含:
- 局部变量表:存储方法参数
sp、ep,局部变量count、i - 操作数栈:临时存储计算过程中的中间数值(比如累加时的临时结果)
- 返回地址:记录当前方法被调用的位置,返回后能回到调用处继续执行
以countPaths(0,3)为例,栈的变化流程:
- 先压入
main方法栈帧,调用countPaths(0,3),压入该方法的栈帧 - 进入循环i=1,调用
countPaths(1,3),压入新栈帧 - 循环i=1,调用
countPaths(2,3),压入新栈帧 - 循环i=1,调用
countPaths(3,3),压入新栈帧;该方法满足sp==ep,返回1,栈帧弹出 countPaths(2,3)处理完i=1后,继续处理i=2到6,每次调用都返回0,最终返回1,栈帧弹出countPaths(1,3)处理完i=1后,处理i=2得到返回值1,累加后count=2,处理i=3到6返回0,最终返回2,栈帧弹出countPaths(0,3)处理完i=1后count=2,i=2返回1后count=3,i=3返回1后count=4,i=4到6返回0,最终返回4,栈帧弹出,回到main方法输出结果
四、count += countPaths(sp + i, ep)的核心逻辑
这行代码是递归的核心,作用是累加所有当前走法对应的后续路径数:
i代表当前掷骰子走出的步数(1-6),sp+i是走i步后的新起点- 递归调用
countPaths(sp+i, ep),得到从新起点到终点的所有路径数 - 把所有i对应的路径数累加,就是当前起点
sp到终点ep的总路径数
比如在sp=0时:
- 走1步到1,从1到3有2条路径
- 走2步到2,从2到3有1条路径
- 走3步直接到终点,有1条路径
- 走4-6步超过终点,无合法路径
- 总和就是2+1+1=4,对应最终结果
内容的提问来源于stack exchange,提问作者Umair Farooq
相关产品推荐
相关产品推荐

