在Udemy上学习Java(和编程)。需要帮助来理解逻辑

时间:2016-05-18 09:22:36

标签: java recursion

我目前正在观看有关递归的视频,我需要一些关于其中逻辑的帮助。

我不理解回归"时刻"算法。 这是代码:

public class App {


    public static void main(String[] args) {

        // E.g. 4! = 4*3*2*1 (factorial 4)

        System.out.println(factorial(5));
    }

    private static int factorial(int value) {
        //System.out.println(value);

        if(value == 1) {
            return 1;
        }

        return factorial(value - 1) * value;
    }

}

我不明白的是return 1;部分。 当该方法计算阶乘4时,它会自动回忆它,直到值变为1。

但是当value == 1时,该方法应该将1返回给方法的调用者。 这个return 1是否会覆盖return factorial(value - 1) * value; ??

显然,我并不完全理解return的工作方式。

提前致谢:)

3 个答案:

答案 0 :(得分:2)

Return 1会覆盖return factorial(value - 1) * value;

但是这个函数正在做的是调用自身,直到值达到1。

一旦值达到1,则满足if条件并且调用return 1部分,完全结束函数(类似于break;会简单地说),所以它会停止执行return factorial(value - 1) * value;

答案 1 :(得分:2)

每次递归的点是“停止点”,条件,当递归不继续时,而是返回值。如果此点不存在,则递归结束。

这就是它的名称:

System.out.println(factorial(5))
-return factorial(4)*5
--return factorial(3)*4
---return factorial(2)*3
----return factorial(1)*2
-----return 1
----return 1*2
---return 2*3
--return 6*4
-return 24*5
System.out.println(120)

我认为当你将“返回”放在递归计数之外时会更清楚,因为你在一行中做了更多的事情。

我制作了这个程序,忽略了“doMinuses”方法,它只使得输出更具可读性。它与您的程序完全相同。您不必阅读它,只需先查看输出。

public class App {
    public static int origValue = 5;

    public static void main(String[] args) {
        System.out.println(factorial(origValue));
    }

    private static int factorial(int value) {
        doMinuses(origValue-value);
        System.out.println("Entered factorial("+value+")");
        if(value == 1) {
        doMinuses(origValue-value);
        System.out.println("Returning 1");
            return 1;
        }

        doMinuses(origValue-value);
        System.out.println("Start countin factorial("+(value-1)+")*"+value);
        int factorialResult = factorial(value - 1) * value;
        doMinuses(origValue-value);
        System.out.println("Returning result for factorial("+(value-1)+")*"+value + " = " + factorialResult);
        return factorialResult;
    }

    private static void doMinuses(int count){
        for (int i = 0; i < count; i++) {
            System.out.print('-');
        }        
    }
}

输出

Entered factorial(5)
Start countin factorial(4)*5
-Entered factorial(4)
-Start countin factorial(3)*4
--Entered factorial(3)
--Start countin factorial(2)*3
---Entered factorial(2)
---Start countin factorial(1)*2
----Entered factorial(1)
----Returning 1
---Returning result for factorial(1)*2 = 2
--Returning result for factorial(2)*3 = 6
-Returning result for factorial(3)*4 = 24
Returning result for factorial(4)*5 = 120
120

打印代码之外的唯一区别是更改此行

return factorial(value - 1) * value; 

两行,因为它是,真正发生的事情(特别是正在发生的事情的顺序)。

        int factorialResult = factorial(value - 1) * value;
        return factorialResult;

我为BEST输出编辑了更多功能:)

public class App {

    public static int origValue = 5;

    public static void main(String[] args) {
        System.out.println(factorial(origValue));
    }

    private static int factorial(int value) {
        doMinuses(origValue - value);
        System.out.println("Entered factorial(" + value + ")");
        if (value == 1) {
            doMinuses(origValue - value);
            System.out.println("Returning 1");
            return 1;
        }

        doMinuses(origValue - value);
        System.out.println("Start countin factorial(" + (value - 1) + ")*" + value);
        int factorialResult = factorial(value - 1);
        doMinuses(origValue - value);
        System.out.println("Finished counting factorial(" + (value - 1) + ") = " + factorialResult);
        doMinuses(origValue - value);
        System.out.println("Returning result for factorial(" + (value - 1) + ")*" + value + " = " + factorialResult + "*" + value + " = " + (factorialResult * value));
        return factorialResult * value;
    }

    private static void doMinuses(int count) {
        for (int i = 0; i < count; i++) {
            System.out.print('-');
        }
    }
}

有这个输出:

Entered factorial(5)
Start countin factorial(4)*5
-Entered factorial(4)
-Start countin factorial(3)*4
--Entered factorial(3)
--Start countin factorial(2)*3
---Entered factorial(2)
---Start countin factorial(1)*2
----Entered factorial(1)
----Returning 1
---Finished counting factorial(1) = 1
---Returning result for factorial(1)*2 = 1*2 = 2
--Finished counting factorial(2) = 2
--Returning result for factorial(2)*3 = 2*3 = 6
-Finished counting factorial(3) = 6
-Returning result for factorial(3)*4 = 6*4 = 24
Finished counting factorial(4) = 24
Returning result for factorial(4)*5 = 24*5 = 120
120

答案 2 :(得分:1)

返回值'1'来自此表达式

return factorial(value - 1) * value;

并且仅在此处使用,以前的行将永远不会被评估。

在这种情况下,递归与循环类似。要了解它是如何工作的,您可以使用调试器,或尝试按顺序写下每条指令(语句,表达式)。

for factorial(3) 它看起来像这样

factorial(3)
if(3==1) //false
factorial(2) //to return factorial(2) * 3 when function becomes evaluated
if(2==1) //false
factorial(1) // //to return factorial(1) * 2 when function becomes evaluated
if(1==1) //true
return 1;
return /*factorial(1) = */ 1 * 2;
return /*factorial(2) = */ 2 * 3; //return 6 - result of your top call of factorial(3) from the main call