public class Factorial {
int factR(int n){
int result;
if(n==1)return 1;
result=factR(n-1)*n;
System.out.println("Recursion"+result);
return result;
}
我知道这个方法会有
的输出 Recursion2
Recursion6
Recursion24
Recursion120
Recursive120
但是,我的问题是java如何存储阶乘的过去值?看起来好像java决定将自下而上的值相乘。这种情况发生的过程是什么?它是由于java如何在其堆栈中存储内存?
答案 0 :(得分:3)
http://www.programmerinterview.com/index.php/recursion/explanation-of-recursion/
值存储在Java的调用堆栈中。由于定义了这种递归函数,它是相反的。你得到n,然后将它乘以n-1的相同函数的值,依此类推,依此类推,直到达到1并在该级别返回1。因此,对于5,它将是5 * 4 * 3 * 2 * 1.无论乘法的方向如何,答案都是相同的。
你可以通过编写一个破坏堆栈并给你一个StackOverflowError的程序来看看它是如何工作的。你不能在调用堆栈上存储无限状态!
public class StackTest {
public static void main(String[] args) {
run(1);
}
private static void run(int index) {
System.out.println("Index: " + index);
run(++index);
}
}
答案 1 :(得分:1)
它实际上并不存储过去的价值观。一点都不它将程序的状态存储在堆栈中,每个方法调用的框架包含数据,例如程序所在的当前行。但是对于堆栈顶部的当前方法,变量result
在任何时候只有一个值。返回并用于在调用此框架的框架中计算result
,依此类推,从而显示自下而上的行为。
使这种不那么混乱的一种方法是暂时从图片中取出递归。假设Java不支持递归,并且只允许方法调用其他不同的方法。如果您仍想采用类似的方法,一种粗略的方法是将factR
方法复制粘贴到多个不同但相似的方法中,例如:
int fact1(int n){
int result;
if(n==1)return 1;
// Here's the difference: call the 'next' method
result=fact2(n-1)*n;
System.out.println("Recursion"+result);
return result;
}
同样定义调用fact2
等的fact3
,尽管最终你必须停止定义新方法,并希望最后一个方法不被调用。这将是一个可怕的计划,但它应该是非常明显的,它是如何工作的,因为没有什么神奇的。有些人认为你可以意识到factR
基本上是在做同样的事情。然后你可以看到Java没有决定'从底部向上乘以值:观察到的行为是给定代码的唯一逻辑可能性。
答案 2 :(得分:0)
我正在努力了解你,
如果有人同样打电话
factR(3)
它是递归过程,所以显然java使用Stack来维护工作流程,
注意:请逐步查看下面的程序任务,并再次注意 在当前任务完成后它回来的地方。
result=factR(2)*3 // again call where n=2
-> result=factR(1)*2 // again call where n=1
-> now n=1 so that it will return 1
-> result=1*2 // after return it will become 6
print "Recursion2" // print remaning stuff
return 2;
result=2*3 // after return it will become 6
print "Recursion3" // print remaning stuff
return 3