这是我使用递归的因子代码。
class Factorial
{
public static void main(String args[])
{
Factorial f = new Factorial();
System.out.println(f.fact(Integer.parseInt(args[0])));
}
private int fact(int num)
{
int result;
if(num == 1)
return 1;
result = fact(num - 1) * num;
return result;
}
}
现在运行这个程序,我做了这个
D:\>java Factorial 3
现在根据进入事实函数的逻辑,其中num = 3,所以它将跳到
result = fact(num - 1) * num;
这将成为
result = fact(3 - 1) * num;
即。 result = fact(2) * num;
在这一步中,我很困惑它是否执行整个步骤,即
result = fact(num - 1) * num;
或只是fact(num - 1)
根据逻辑,它应该做的是调用事实函数。因此,程序的控制再次到达事实函数的开始,其中num = 2.它将再次跳到
result = fact(num - 1) * num;
所以,它会变成
result = fact(2 - 1) * num;
即。 result = fact(1) * num;
现在再次,它应该调用事实函数而不执行整个语法&再次到达事实方法的开始,其中num = 1.这个时间num == 1将匹配& 1将被退回。现在它将返回
result = fact(num - 1) * num;
所以,它会变成
result = fact(1 - 1) * num;
即。 result = fact(0) * num;
现在接下来会发生什么?
我是对的吗?如果不是会有什么修正?
我不清楚这个递归程序的流程。
答案 0 :(得分:2)
所以,它会变成
result = fact(1 - 1) * num;
不。对于num = 2
,
result = fact(num - 1) * num;
变为
result = 1 * num; // i.e. 1 * 2
fact
返回一个值,这意味着整个通话必须替换为该值。
不确定为什么你甚至会认为num
发生了变化。您的代码中没有num = ...
。
答案 1 :(得分:2)
我在程序中添加了一些跟踪。执行它并查看输出。应该很容易理解。
package snippet;
class Factorial {
public static void main(String args[]) {
Factorial f = new Factorial();
System.out.println(f.fact(Integer.parseInt("5")));
}
private int fact(int num) {
int result;
if (num == 1)
return 1;
result = fact(num - 1) * num;
System.out.println("fact(" + num + ") = " + result + " = fact(" + (num - 1) + ") * " + num);
return result;
}
}
事实(2)= 2 =事实(1)* 2
事实(3)= 6 =事实(2)* 3
事实(4)= 24 =事实(3)* 4
事实(5)= 120 =事实(4)* 5
120
答案 2 :(得分:2)
您的逻辑是正确的,但您已经 3个基本错误。 如果我们以你为榜样; 首先运行程序
D:\>java Factorial 3
然后你有第一个错误因为根据逻辑所有" num"必须由" 3"取代。所以你得到:
result = fact(3 - 1) * 3;
即:
result = fact(2)*3;
然后我们有第二个错误因为根据fact(num)的定义,
fact(2) = fact(2-1)*2
所以我们确实有
result = (fact(2-1)*2)*3
在
中评估result = (fact(1)*2)*3
并且这里有第三个错误,因为再次根据事实(num)定义:fact(1) = 1
而不是fact(1) = fact(1-1)*1
所以我们终于有了:
result = ((1)*2)*3
如果您在调试器中跟随所有调用序列,那么为了更明确,您将会有类似这样的内容(我在括号中放置变量的值):
private int fact(num{3})
{
int result;
if(num{3}== 1)
return 1;
result = fact(num{3} - 1) * num{3};
private int fact(num{3-1})
{
int result;
if(num{3-1}== 1)
result = fact(num{3-1} - 1) * num{3-1};
private int fact(num{3-1-1})
{
int result;
if(num{3-1-1}== 1)
return 1;
}
return result{1*{3-1}};
}
return result{{1*{3-1}}*3};
}
答案 3 :(得分:1)
调用f.fact(3)正在扩展以下步骤:
1. result = fact(3 - 1) * 3 = fact(2) * 3
2. result = (fact(2 - 1) * 2) * 3 = (fact(1) * 2) * 3
3. result = 1 * 2 * 3 because fact(1) returns 1.
答案 4 :(得分:1)
除非我们达到停止条件:
fact(num) = fact(num - 1) * num;
因此:
fact(3) = fact(3 - 1) * 3;
记住fact(1)= 1(来自fact()
方法早期的if语句):
fact(3) = fact(2) * 3;
fact(2) = fact(1) * 2;
fact(1) = 1;
替换每个元素:
fact(3) = 1 * 2 * 3;
递归用于反复深入研究过程,直到遇到停止条件 - 在这种情况下,当num = 1时。
答案 5 :(得分:1)
您的实施是正确的,但当您从fact(1-1) * 1
的方法返回时,它永远不会达到if(num == 1)
州。
num
变量仅限于方法参数的范围。因此,对于fact
方法num
的每个调用,都会为变量分配一个新值(即num-1),并且仅限于该参数范围。因此,当fact(num-1)
返回时,num的值将是原始值而不是num-1
。
答案 6 :(得分:1)
你的例子的流程是这样的。
第1步。事实(3)* 3; //用num值3调用函数
第2步。事实(2)* 2; //再次使用num = 2来调用fact()方法
第3步。事实(1)* 1; //现在num == 1将匹配& 1将被退回。
一世。即,
1 * 1 = 1 ; //现在,将分别执行步骤2和1
步骤2. 1 * 2 = 2 ;
步骤1. 2 * 3 = 6 ;
因此,最终答案将是 6
注意:在步骤3中,值为返回,因此不会再次调用此结果= fact(0)* num; //你提到的问题。