我目前正在观看有关递归的视频,我需要一些关于其中逻辑的帮助。
我不理解回归"时刻"算法。 这是代码:
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
的工作方式。
提前致谢:)
答案 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