了解递归阶乘中的 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 求值后应用。