先写停,再问更小的自己
这一课只练一件事:把问题说成更小的同类问题,这就是 。先写 ,再写一次 。用 countdown(3) 追踪三层,把 想成一叠任务卡。建议掌握再用同样想法写 。完成四个小任务:选出拆法,走三层调用,再看边界与无限递归。这里不会在浏览器里运行 C++。
任务 1:先选出怎么拆成更小的同类问题
不是魔法,只是“先处理现在,再处理更小的同样问题”。必须先有 ,再写 。点不认识的词可看基础解释。
必会:能先写出终止条件。这里不会在浏览器里运行 C++,只练习选择和走过程。
从 n 数到 1,该怎么拆?同类问题 · 必会
什么时候必须停下来?终止条件 · 必会
任务 2:按顺序追踪 countdown(3)
最小示例:先处理 n,再 countdown(n - 1)。按顺序点三步,走进 countdown(3)、countdown(2)、countdown(1)。这里不会在浏览器里运行 C++。
必会:能手工追踪三层调用。边界:n==1 时直接返回;不要跳过中间的 countdown(2)。
- void countdown(int n) {
- if (n == 1) return; // 边界
- countdown(n - 1); // 更小的同类问题
- }
三层调用追踪完了,现在亲手把阶乘的 那一行敲出来:当前这一层乘上更小一号的同类问题。下面是只读脚手架, 已经写好,只留一空给你敲键盘。
- int fact(int n) {
- if (n == 1) return 1; // 边界:到 1 就停
- return ; // 3! = 3 * 2!
- }
return n * fact(n - 1); // 3! = 3 * 2!:当前层乘上更小一号的同类问题
任务 3:用同样想法写阶乘,并看忘写边界会怎样
建议掌握: 也是更小的同类问题,n! = n * (n-1)!。必会还包括说明无限递归为何发生:没有 , 会一直加任务卡。
必会 / 建议掌握 / 拓展:必会是先写终止条件、追踪三层调用。建议掌握是 3! = 3 * 2! 且 1! = 1,以及说明忘写边界会无限递归。归并排序、记忆化和尾递归优化是拓展,现在不用当硬门槛。
- int fact(int n) {
- if (n == 1) return 1; // 边界
- return n * fact(n - 1); // 3! = 3 * 2!
- }
先选出 3! 该怎么写成更小的同类问题:
再选出忘了写边界会发生什么:
任务 4:随机小测,看看你是否真的懂了
每次从本课题库抽出三道不同的选择题。题目与解析已通过校验,答完后看解析,不要只看分数;拿不准就回到对应任务再看一遍。