我试图了解递归如何在阶乘函数中起作用。我应该打印什么,以便我可以看到每次递归调用期间实际发生了什么? 这是代码:
#include <stdio.h>
#include <stdlib.h>
long factorial(long number) {
if(number <= 1) {
return 1;
} else {
return number * factorial(number - 1);
}
}
int main() {
int i;
for(i = 0; i <= 10; i++) {
printf("%2d ! = %ld\n", i, factorial(i));
}
return 0;
}
答案 0 :(得分:4)
以下代码
#include <stdio.h>
#include <stdlib.h>
long factorial (int level, long number){
int result;
printf("[%03d] Calculating: %d\n", level, number);
if(number <= 1)
{
result = 1;
}
else
{
result = number * factorial(level+1, number - 1);
}
printf("[%03d] Returning: %d\n", level, result);
return result;
}
int main(){
int i;
for(i = 0; i <= 10; i++)
{
printf("%2d ! = %ld\n", i, factorial(0, i));
}
return 0;
}
给出了这个输出
[000] Calculating: 10
[001] Calculating: 9
[002] Calculating: 8
[003] Calculating: 7
[004] Calculating: 6
[005] Calculating: 5
[006] Calculating: 4
[007] Calculating: 3
[008] Calculating: 2
[009] Calculating: 1
[009] Returning: 1
[008] Returning: 2
[007] Returning: 6
[006] Returning: 24
[005] Returning: 120
[004] Returning: 720
[003] Returning: 5040
[002] Returning: 40320
[001] Returning: 362880
[000] Returning: 3628800
10 ! = 3628800
其中[XXX]是当前的递归级别。
答案 1 :(得分:2)
试试这个
long factorial (long number){
if(number <= 1){
return 1;
}else{
return number * factorial(number - 1);
}
}
假设我们将4作为第一个参数传递,然后函数求值为:
long factorial (long number /*==4*/){
if(4 <= 1){//false
return 1;
}else{
return 4 * factorial(4 - 1);
}
}
注意返回in else无法完成,因为它调用另一个函数 - factorial(4-1)。 所以4必须乘以阶乘(3)的结果。所以它去执行阶乘(3)。
现在我们得到
long factorial (long number /*==3*/){
if(3 <= 1){//false
return 1;
}else{
return 3 * factorial(3 - 1);
}
}
但是这里的回归再次无法完成,因为它将因子称为3-1 = 2。
现在需要评估阶乘(2),其结果将乘以3并传递给前一次返回。再次:
long factorial (long number /*==2*/){
if(2 <= 1){//false
return 1;
}else{
return 2 * factorial(2 - 1);
}
}
我们有类似的问题。但是现在当执行阶乘(2-1)时,函数将立即返回1,因此上面的行将返回2.
此结果将插入前一次返回的结果,给出2 * 3;这个结果 - 6 - 将插入前一次返回并产生6 * 4,这是最终结果24。
答案 2 :(得分:2)
对于一些荒谬的事情,要考虑factorial
的主体:
long factorial_body(long number) {
if(number <= 1) {
return 1;
} else {
return number * factorial(number - 1);
}
}
然后,重写factorial
以致电factorial_body
,在通话中打印一些内容。
long factorial (long number) {
static char output[4096];
static int level;
static int index;
int saved_index;
long result;
switch (level++) {
case 1: index += snprintf(output + index, sizeof(output) - index, "= ");
default: index += snprintf(output + index, sizeof(output) - index,
"%ld x ", number + 1);
case 0: snprintf(output + index, sizeof(output) - index,
"factorial(%ld)\n", number);
}
saved_index = index;
printf("%s", output);
result = factorial_body(number);
index = saved_index;
snprintf(output + index, sizeof(output) - index,
--level ? "%ld\n" : "= %ld\n", result);
printf("%s", output);
return result;
}
factorial(10)
将生成以下输出:
factorial(10)
= 10 x factorial(9)
= 10 x 9 x factorial(8)
= 10 x 9 x 8 x factorial(7)
= 10 x 9 x 8 x 7 x factorial(6)
= 10 x 9 x 8 x 7 x 6 x factorial(5)
= 10 x 9 x 8 x 7 x 6 x 5 x factorial(4)
= 10 x 9 x 8 x 7 x 6 x 5 x 4 x factorial(3)
= 10 x 9 x 8 x 7 x 6 x 5 x 4 x 3 x factorial(2)
= 10 x 9 x 8 x 7 x 6 x 5 x 4 x 3 x 2 x factorial(1)
= 10 x 9 x 8 x 7 x 6 x 5 x 4 x 3 x 2 x 1
= 10 x 9 x 8 x 7 x 6 x 5 x 4 x 3 x 2
= 10 x 9 x 8 x 7 x 6 x 5 x 4 x 6
= 10 x 9 x 8 x 7 x 6 x 5 x 24
= 10 x 9 x 8 x 7 x 6 x 120
= 10 x 9 x 8 x 7 x 720
= 10 x 9 x 8 x 5040
= 10 x 9 x 40320
= 10 x 362880
= 3628800
如果以上输出有助于增强您对递归的理解,我很怀疑。但是,努力了解打印代码的工作原理可能会更好地理解递归。
答案 3 :(得分:1)
而不是print语句添加您要打印到数组或其他内容的任何内容,然后在递归函数完成后按插入顺序(fifo)打印出来。
答案 4 :(得分:1)
这应该会让你跟踪 factorial 的执行情况,并带有缩进:
long factorial(long number, int depth){
printf("%*s enter, number = %d\n", 4*depth, "", number);
long result = 1;
if (number > 1) result = number * factorial(number-1, depth+1);
printf("%*s exit, result = %d\n", 4*depth, "", result);
return result;
}