递归的逻辑是什么

时间:2015-08-06 06:17:00

标签: java recursion

这是我使用递归的因子代码。

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;

现在接下来会发生什么?

我是对的吗?如果不是会有什么修正?

我不清楚这个递归程序的流程。

7 个答案:

答案 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; //你提到的问题。