这段代码如何在编译器中执行?

时间:2016-04-24 10:24:07

标签: java

我是Java的新手,我正在阅读几本关于它的书。 我无法弄清楚这段代码的输出是如何产生的:

import java.util.*;

class myclass {
    public static void main(String[] args) {
        Scanner myScanner = new Scanner(System.in);
        System.out.println(factorial(myScanner.nextInt())+"\n");
    }

    public static int factorial(int n) {
        if (n==0) {
           return 1;
        } else {    
            int recurse = factorial(n-1);
            int result = recurse*n;
            return result;
        }
    }
}

任何人都可以一步一步地为我解释一下吗? 我理解主要方法和Scanner课程,但我不明白,当我在输入时输入8这样的整数时,我会在输出中得到40320

3 个答案:

答案 0 :(得分:0)

函数 factorial 使用递归来求解阶乘。这意味着该函数多次调用自身,直到n变为0(其中它返回1)。

因此,对于n = 3,程序首先将结果设置为

first.toArray

现在你可以将这些东西加在一起,因为它知道Factorial(0),Factorial(1),Factorial(2)和Factorial(3)是什么。

然后变成:

second.toArray

答案 1 :(得分:0)

首先:Factorial function

我认为你不理解递归因子函数。

功能声明:

public static int factorial(int n){

因子0为1(例外):

if(n==0){
    return 1;
}

如果用户引入的数字不是0,则:

    else { 
        int recurse = factorial(n-1);
        int result = recurse*n;
        return result;
   }
  1. 在这种情况下,例如,用2. recurse = factorial(2-1)调用函数,等到对函数的调用结束(在这种情况下调用相同的函数,但这不是问题,等到函数调用结束)。因此呼叫factorial(2-1)。 继续......

  2. factorial(1),n==0 false ,因此进入else语句。呼叫factorial(1-1)。另一次等待功能因子(1-1)结束。 继续......

  3. factorial(0),n==0 true ,因此return 1。对函数的调用结束了,现在我们将继续执行第2步。

  4. 在步骤2中继续使用阶乘(1):阶乘(1-1)返回1并将其存储在recurseint result = recurse * n中,因此结果= 1·1。最后在此步骤中返回result(1)。现在我们转到仍然在factorial(1)调用中等待的第1步。

  5. 在步骤1中继续阶乘(2):阶乘(2-1)返回1并将其存储在recurse中。 int result = recurse * n所以结果= 1·2。并返回result(2)。

  6. 最后阶乘(2)返回2.想想阶乘(3),4,5,6,7,最后你会理解阶乘8.最重要的是,当你调用同一个函数时是的,它将状态保存在堆栈中并等到它完成。

答案 2 :(得分:0)

当您正确格式化代码时,代码更容易完成,因此请在将来执行此操作。有时,当您使代码更简洁时,代码也更容易完成。请注意,您可以"内联" result变量:

public static int factorial(int n) {

    if (n == 0) {
        return 1; 
    }
    else {
        int recurse = factorial(n - 1);
        return recurse * n;
    }
}

或更简单:

public static int factorial(int n) {
    if (n == 0) {
        return 1;
    }
    return n * factorial(n-1);
}

现在让我们尝试一些价值观。让我们尝试使用" 0":

的值
public static int factorial(int n) {
    if (n == 0) { 
        return 1; //<-- Returns 1
    }
    return n * factorial(n-1);
}

好的,那是对的:0! = 1。

让我们尝试使用&#34; 1&#34;:

的值
public static int factorial(int n) {
    if (n == 0) { 
        return 1; //not reached
    }
    return n * factorial(n-1); //<-- 1 * factorial(0) = 1 * 1 = 1
}

好:1! = 1。

让我们尝试使用&#34; 8&#34;的价值:

public static int factorial(int n) {
    if (n == 0) { 
        return 1; //not reached
    }
    return n * factorial(n-1); //<-- 8 * factorial(8-1) = 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1 = 40320
}

从8开始这是有道理的! = 40,320。

这样做的方式称为递归,因为该方法本质上是调用自身。如果做得好,递归是编程的一个很好的部分,因为代码通常相当简洁并且是"divide and conquer"心态之一。这是编程中的入门概念。

优秀的程序员将始终在思考价值体系。因此,在这种情况下,如果n为-1,则函数将提供StackOverFlow错误。 (您可以将代码更改为if (n <= 1))。