了解递归阶乘中的 Java 行为
Understanding Java behaviour in recursive factorial
我创建了两个递归方法来计算阶乘,如下所示:
private int fact1(int n) {
if (n == 0 || n == 1)
return 1;
return n * fact1(--n);
}
private int fact2(int n) {
if (n == 0 || n == 1)
return 1;
return fact2(--n) * n;
}
当我调用 fact1(4)
时,它 returns 24
。当我调用 fact2(4)
时,它 returns 6
(EDIT: 不是 returning 18
而是 6
).我知道第二种方法是制作 3 * 2 * 1,但我不明白为什么不是 4 * 3 * 2 * 1.
如果我将 return 更改为
,也会发生同样的情况
//fact3(4) returns 60.
return (n + 1) * fact3(--n); // wrong
//fact4(4) returns 24
return fact4(--n) * (n + 1); // works
为什么该方法表现出这种行为?
问题是关于不同的行为。我知道 n * fact(n-1)
是更好的解决方法。
有人可以帮助我理解这个表达式的评估吗?谢谢!
这一切都归结为这些表达式之间的差异:
return n * f(--n);
return f(--n) * n;
当n = 4
时,这些表达式的计算方式如下:
return 4 * f(3);
return f(3) * 3;
因为计算--n
的时刻,n
的值减1。
这就是前缀 --
运算符的工作原理。
手动递归计算整个表达式可能会有所帮助。第一个:
// first
return 4 * f(3);
return 4 * 3 * f(2);
return 4 * 3 * 2 * f(1);
return 4 * 3 * 2 * 1;
// second
return f(3) * 3;
return f(2) * 2 * 3;
return f(1) * 1 * 2 * 3;
return 1 * 1 * 2 * 3;
在相关说明中,猜猜这将如何评估:
return f(n--) * n;
它将是:
return f(4) * 3;
因为这里使用了后缀 --
运算符:-1 减量将在 f(...)
中的 n
求值后应用。
我创建了两个递归方法来计算阶乘,如下所示:
private int fact1(int n) {
if (n == 0 || n == 1)
return 1;
return n * fact1(--n);
}
private int fact2(int n) {
if (n == 0 || n == 1)
return 1;
return fact2(--n) * n;
}
当我调用 fact1(4)
时,它 returns 24
。当我调用 fact2(4)
时,它 returns 6
(EDIT: 不是 returning 18
而是 6
).我知道第二种方法是制作 3 * 2 * 1,但我不明白为什么不是 4 * 3 * 2 * 1.
如果我将 return 更改为
,也会发生同样的情况//fact3(4) returns 60.
return (n + 1) * fact3(--n); // wrong
//fact4(4) returns 24
return fact4(--n) * (n + 1); // works
为什么该方法表现出这种行为?
问题是关于不同的行为。我知道 n * fact(n-1)
是更好的解决方法。
有人可以帮助我理解这个表达式的评估吗?谢谢!
这一切都归结为这些表达式之间的差异:
return n * f(--n);
return f(--n) * n;
当n = 4
时,这些表达式的计算方式如下:
return 4 * f(3);
return f(3) * 3;
因为计算--n
的时刻,n
的值减1。
这就是前缀 --
运算符的工作原理。
手动递归计算整个表达式可能会有所帮助。第一个:
// first
return 4 * f(3);
return 4 * 3 * f(2);
return 4 * 3 * 2 * f(1);
return 4 * 3 * 2 * 1;
// second
return f(3) * 3;
return f(2) * 2 * 3;
return f(1) * 1 * 2 * 3;
return 1 * 1 * 2 * 3;
在相关说明中,猜猜这将如何评估:
return f(n--) * n;
它将是:
return f(4) * 3;
因为这里使用了后缀 --
运算符:-1 减量将在 f(...)
中的 n
求值后应用。