用递归理解primeFactorsR方法

时间:2012-05-23 06:18:48

标签: java recursion

我有以下方法在这种情况下显示数字的所有素数倍数20.我理解该方法的大多数递归行为,但是在打印数字5之后我有点困惑,为什么n又回来了在前一次调用中为5时(即执行第三个递归方法时)为10

public class Tester {     

    static boolean isPrime(int p)
    {
        for(int i = 2; i < p; i++)
        {
            if(p % i == 0) return false;
        }
        return true;
    }


   public static void primeFactors(int n)
   {
       primeFactorsR(n, n-1);
   }

   static int count1 = 1, count2 = 1, count3 = 1, count4 = 1;

   public static void primeFactorsR(int n, int m)
      {
         if(isPrime(n))
         {
             System.out.println(n);
             System.out.println("method1 " +count1++);
         }     
         else
            if(n % m == 0)
            {
               System.out.println("n " + n + " m " + m);
               System.out.println("method2: " + count2++);
               primeFactorsR(m, m-1);

               System.out.println("n " + n + " m " + m);
               System.out.println("method3: " + count3++);
               primeFactorsR(n/m, (n/m)-1);              
            }
            else
            {
               System.out.println("n " + n + " m " + m);
               //System.out.println("n " + n + " m - 1 " + ( m-1));
               System.out.println("method4: " + count4++);
               primeFactorsR(n, m-1);
            }
      }


    public static void main(String[] args) {  


           primeFactors(20);        

    }
}

输出

n 20 m 19
method4: 1
n 20 m 18
method4: 2
n 20 m 17
method4: 3
n 20 m 16
method4: 4
n 20 m 15
method4: 5
n 20 m 14
method4: 6
n 20 m 13
method4: 7
n 20 m 12
method4: 8
n 20 m 11
method4: 9
n 20 m 10
method2: 1
n 10 m 9
method4: 10
n 10 m 8
method4: 11
n 10 m 7
method4: 12
n 10 m 6
method4: 13
n 10 m 5
method2: 2
5
method1 1
n 10 m 5
method3: 1
2
method1 2
n 20 m 10
method3: 2
2
method1 3
BUILD SUCCESSFUL (total time: 1 second)

2 个答案:

答案 0 :(得分:0)

我向控制台输出添加了更多信息,以使递归调用链可见 recursionLevel显示递归的深度 每个primeFactorsR - 函数调用都会收到唯一ID(请参阅funcId - 变量) 函数id的序列创建了唯一的递归调用路径 - recursionPath

public class Tester {

    static boolean isPrime(int p) {
        for (int i = 2; i < p; i++) {
            if (p % i == 0) return false;
        }
        return true;
    }

    public static void primeFactors(int n, int recursionLevel) {
        primeFactorsR(n, n - 1, recursionLevel, null);
    }

    static int count1 = 1, count2 = 1, count3 = 1, count4 = 1;
    private static int recursionId = 1;

    public static void primeFactorsR(int n, int m, int recursionLevel, String recursionPath) {
        int funcId = recursionId++;

        if (recursionPath == null)
            recursionPath = String.format("%s", funcId);
        else
            recursionPath = String.format("%s-%s", recursionPath, funcId);

        if (isPrime(n)) {
            System.out.println(String.format("n %s recursionLevel %s recursionPath %s", n, recursionLevel, recursionPath));
            System.out.println("method1 " + count1++);
        } else if (n % m == 0) {
            System.out.println(String.format("n %s m %s recursionLevel %s recursionPath %s", n, m, recursionLevel, recursionPath));
            System.out.println("method2: " + count2++);
            primeFactorsR(m, m - 1, recursionLevel + 1, recursionPath);

            System.out.println(String.format("n %s m %s recursionLevel %s recursionPath %s", n, m, recursionLevel, recursionPath));
            System.out.println("method3: " + count3++);
            primeFactorsR(n / m, (n / m) - 1, recursionLevel + 1, recursionPath);
        } else {
            System.out.println(String.format("n %s m %s recursionLevel %s recursionPath %s", n, m, recursionLevel, recursionPath));
            //System.out.println("n " + n + " m - 1 " + ( m-1));
            System.out.println("method4: " + count4++);
            primeFactorsR(n, m - 1, recursionLevel + 1, recursionPath);
        }
    }

    public static void main(String[] args) {
        primeFactors(20, 1);
    }

}

结果:

n 20 m 19 recursionLevel 1 recursionPath 1
method4: 1
n 20 m 18 recursionLevel 2 recursionPath 1-2
method4: 2
n 20 m 17 recursionLevel 3 recursionPath 1-2-3
method4: 3
n 20 m 16 recursionLevel 4 recursionPath 1-2-3-4
method4: 4
n 20 m 15 recursionLevel 5 recursionPath 1-2-3-4-5
method4: 5
n 20 m 14 recursionLevel 6 recursionPath 1-2-3-4-5-6
method4: 6
n 20 m 13 recursionLevel 7 recursionPath 1-2-3-4-5-6-7
method4: 7
n 20 m 12 recursionLevel 8 recursionPath 1-2-3-4-5-6-7-8
method4: 8
n 20 m 11 recursionLevel 9 recursionPath 1-2-3-4-5-6-7-8-9
method4: 9
n 20 m 10 recursionLevel 10 recursionPath 1-2-3-4-5-6-7-8-9-10
method2: 1
n 10 m 9 recursionLevel 11 recursionPath 1-2-3-4-5-6-7-8-9-10-11
method4: 10
n 10 m 8 recursionLevel 12 recursionPath 1-2-3-4-5-6-7-8-9-10-11-12
method4: 11
n 10 m 7 recursionLevel 13 recursionPath 1-2-3-4-5-6-7-8-9-10-11-12-13
method4: 12
n 10 m 6 recursionLevel 14 recursionPath 1-2-3-4-5-6-7-8-9-10-11-12-13-14
method4: 13
n 10 m 5 recursionLevel 15 recursionPath 1-2-3-4-5-6-7-8-9-10-11-12-13-14-15
method2: 2
n 5 recursionLevel 16 recursionPath 1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-16
method1 1
n 10 m 5 recursionLevel 15 recursionPath 1-2-3-4-5-6-7-8-9-10-11-12-13-14-15
method3: 1
n 2 recursionLevel 16 recursionPath 1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-17
method1 2
n 20 m 10 recursionLevel 10 recursionPath 1-2-3-4-5-6-7-8-9-10
method3: 2
n 2 recursionLevel 11 recursionPath 1-2-3-4-5-6-7-8-9-10-18
method1 3

从结果中检查以下行:

n 10 m 5 recursionLevel 15 recursionPath 1-2-3-4-5-6-7-8-9-10-11-12-13-14-15
method2: 2
n 5 recursionLevel 16 recursionPath 1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-16
method1 1
n 10 m 5 recursionLevel 15 recursionPath 1-2-3-4-5-6-7-8-9-10-11-12-13-14-15
method3: 1

ID为15的函数,名为ID 16的函数,打印行:

n 5 recursionLevel 16 recursionPath 1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-16

之后,调用从16到15返回,函数15中的n值仍为10

答案 1 :(得分:0)

这是因为在你的第二个if语句n % m == 0中,它会对primeFactorsR进行两次调用。第一个调用会引导您深入到堆栈中,其中5是素数。它然后返回堆栈,直到它到达它停止的位置,并在第二个打印语句上移动,给你第二个n 10 m 5.这是你的输出,它缩进每一层并打印出它在堆栈中的深度当它第一次进入primeFactorsR并完成时。它向右前进的位置更深入到堆栈中,上面的层暂停。当图层完成处理后,它将返回上面的图层,如果该图层有更多要做,那么它将从它停止的位置继续。

We are the top layer
n 20 m 19
method4: 1
   We are 1 layers deep
   n 20 m 18
   method4: 2
      We are 2 layers deep
      n 20 m 17
      method4: 3
         We are 3 layers deep
         n 20 m 16
         method4: 4
            We are 4 layers deep
            n 20 m 15
            method4: 5
               We are 5 layers deep
               n 20 m 14
               method4: 6
                  We are 6 layers deep
                  n 20 m 13
                  method4: 7
                     We are 7 layers deep
                     n 20 m 12
                     method4: 8
                        We are 8 layers deep
                        n 20 m 11
                        method4: 9
                           We are 9 layers deep
                           n 20 m 10
                           method2: 1
                              We are 10 layers deep
                              n 10 m 9
                              method4: 10
                                 We are 11 layers deep
                                 n 10 m 8
                                 method4: 11
                                    We are 12 layers deep
                                    n 10 m 7
                                    method4: 12
                                       We are 13 layers deep
                                       n 10 m 6
                                       method4: 13
                                          We are 14 layers deep
                                          n 10 m 5
                                          method2: 2
                                             We are 15 layers deep
                                             Prime 5
                                             method1 1
                                             Finished with layer 15
                                          n 10 m 5
                                          method3: 1
                                             We are 15 layers deep
                                             Prime 2
                                             method1 2
                                             Finished with layer 15
                                          Finished with layer 14
                                       Finished with layer 13
                                    Finished with layer 12
                                 Finished with layer 11
                              Finished with layer 10
                           n 20 m 10
                           method3: 2
                              We are 10 layers deep
                              Prime 2
                              method1 3
                              Finished with layer 10
                           Finished with layer 9
                        Finished with layer 8
                     Finished with layer 7
                  Finished with layer 6
               Finished with layer 5
            Finished with layer 4
         Finished with layer 3
      Finished with layer 2
   Finished with layer 1
Finished