双递归-Java

双递归-Java,java,recursion,Java,Recursion,我有个问题。当我得到这个代码时,我无法理解如何思考: public class MysteryClass { public static void mystery(int n) { if (n > 0){ mystery(n-1); System.out.print(n * 4); mystery(n-1); } } public static void main(String[] args)

我有个问题。当我得到这个代码时,我无法理解如何思考:

public class MysteryClass {
   public static void mystery(int n) {
      if (n > 0){
         mystery(n-1);
         System.out.print(n * 4);
         mystery(n-1);
      }
   }

   public static void main(String[] args) {
      MysteryClass.mystery(3);
   }
}

答案是4841284,但我不知道他们是怎么得到的。。有人能解释一下吗

函数调用就是这样进行的。要了解更多,请拿一支铅笔和一张纸,画出发生了什么。首先,为了神秘而做。然后继续mystery2和mystery3

mystery(3)
    msytery(2)
        mystery(1)
            mystery(0)
            prints 1 * 4
            mystery(0)
        prints 2 * 4
        mystery(1)
            mystery(0)
            prints 1 * 4
            mystery(0)
    prints 3 * 4
    msytery(2)
        mystery(1)
            mystery(0)
            prints 1 * 4
            mystery(0)
        prints 2 * 4
        mystery(1)
            mystery(0)
            prints 1 * 4
            mystery(0)

这就是函数调用的方式。要了解更多,请拿一支铅笔和一张纸,画出发生了什么。首先,为了神秘而做。然后继续mystery2和mystery3

mystery(3)
    msytery(2)
        mystery(1)
            mystery(0)
            prints 1 * 4
            mystery(0)
        prints 2 * 4
        mystery(1)
            mystery(0)
            prints 1 * 4
            mystery(0)
    prints 3 * 4
    msytery(2)
        mystery(1)
            mystery(0)
            prints 1 * 4
            mystery(0)
        prints 2 * 4
        mystery(1)
            mystery(0)
            prints 1 * 4
            mystery(0)
在mysteryint n方法中,使用

mystery(n-1);
在递归调用之间,输出原始调用的值乘以4

这意味着,即使在第一次输出之前,您也可以使用n-1再次调用该方法,并在调用中使用n-1再次调用它。第一个号码是第一次呼叫的第二次迭代。第二个数字是第一次迭代,依此类推。这很难用语言来解释。通过一步一步地调试,您可能会更成功地理解它。

在mysteryint n方法中,您使用两次调用它自己

mystery(n-1);
在递归调用之间,输出原始调用的值乘以4


这意味着,即使在第一次输出之前,您也可以使用n-1再次调用该方法,并在调用中使用n-1再次调用它。第一个号码是第一次呼叫的第二次迭代。第二个数字是第一次迭代,依此类推。这很难用语言来解释。通过一步一步地调试,您可能会更成功地理解它。

想想最初的几个调用,模式是显而易见的

n = 3
mystery(n-1); ->

   // recursive call
   n = 2 
   mystery(n-1); ->

      // recursive call
      n = 1
      mystery(n-1); ->

         // inside recursion      
         n = 0 // Do nothing

      System.out.print(n * 4);  // = 4
      mystery(n-1);

         // inside recursion
         n = 0 // Do nothing

   System.out.print(n * 4);  // = 8
   mystery(n-1); ->

      // inside recursion
      n = 1
      mystery(n-1); ->

         // inside recursion
         n = 0 // Do nothing

      System.out.print(n * 4);  // = 4
      mystery(n-1);

         // inside recursion
         n = 0 // Do nothing

。。。你得到了这个想法

想想最初的几个电话,模式就显而易见了

n = 3
mystery(n-1); ->

   // recursive call
   n = 2 
   mystery(n-1); ->

      // recursive call
      n = 1
      mystery(n-1); ->

         // inside recursion      
         n = 0 // Do nothing

      System.out.print(n * 4);  // = 4
      mystery(n-1);

         // inside recursion
         n = 0 // Do nothing

   System.out.print(n * 4);  // = 8
   mystery(n-1); ->

      // inside recursion
      n = 1
      mystery(n-1); ->

         // inside recursion
         n = 0 // Do nothing

      System.out.print(n * 4);  // = 4
      mystery(n-1);

         // inside recursion
         n = 0 // Do nothing

。。。您得到了想法

您可以修改类以打印调用顺序:

public class MysteryClass {
  static int COUNTER = 0;
  public static void mystery(int n) {
    int callOrder = COUNTER;
    COUNTER++;
     if (n > 0){
        mystery(n-1);
        System.out.println(n * 4 +"  (order: "+callOrder+", n: "+n+")");
        mystery(n-1);
     } else {
       System.out.println("wont print and wont recurse(negative): " +"(order: "+callOrder+", n: "+n+")");
     }
  }

  public static void main(String[] args) {
     MysteryClass.mystery(3);
  }
}
这张照片是:

wont print and wont recurse(negative): (order: 3, n: 0)
4  (order: 2, n: 1)
wont print and wont recurse(negative): (order: 4, n: 0)
8  (order: 1, n: 2)
wont print and wont recurse(negative): (order: 6, n: 0)
4  (order: 5, n: 1)
wont print and wont recurse(negative): (order: 7, n: 0)
12  (order: 0, n: 3)
wont print and wont recurse(negative): (order: 10, n: 0)
4  (order: 9, n: 1)
wont print and wont recurse(negative): (order: 11, n: 0)
8  (order: 8, n: 2)
wont print and wont recurse(negative): (order: 13, n: 0)
4  (order: 12, n: 1)
wont print and wont recurse(negative): (order: 14, n: 0)
您可以验证@bgamlath在回答中所说的内容是否与发生的情况相符。顺序是指调用递归方法的顺序


你也可以看到测谎,调用顺序为0,中间打印12,递归结果4, 8, 4的结果与上面和贝娄的结果相同。如果从4开始,您将看到一个更大的对称性示例,这是由于前后的递归。

您可以修改类以打印调用顺序:

public class MysteryClass {
  static int COUNTER = 0;
  public static void mystery(int n) {
    int callOrder = COUNTER;
    COUNTER++;
     if (n > 0){
        mystery(n-1);
        System.out.println(n * 4 +"  (order: "+callOrder+", n: "+n+")");
        mystery(n-1);
     } else {
       System.out.println("wont print and wont recurse(negative): " +"(order: "+callOrder+", n: "+n+")");
     }
  }

  public static void main(String[] args) {
     MysteryClass.mystery(3);
  }
}
这张照片是:

wont print and wont recurse(negative): (order: 3, n: 0)
4  (order: 2, n: 1)
wont print and wont recurse(negative): (order: 4, n: 0)
8  (order: 1, n: 2)
wont print and wont recurse(negative): (order: 6, n: 0)
4  (order: 5, n: 1)
wont print and wont recurse(negative): (order: 7, n: 0)
12  (order: 0, n: 3)
wont print and wont recurse(negative): (order: 10, n: 0)
4  (order: 9, n: 1)
wont print and wont recurse(negative): (order: 11, n: 0)
8  (order: 8, n: 2)
wont print and wont recurse(negative): (order: 13, n: 0)
4  (order: 12, n: 1)
wont print and wont recurse(negative): (order: 14, n: 0)
您可以验证@bgamlath在回答中所说的内容是否与发生的情况相符。顺序是指调用递归方法的顺序

你也可以看到测谎,调用顺序为0,中间打印12,递归结果4, 8, 4的结果与上面和贝娄的结果相同。如果你从4开始,你会看到一个更大的对称性的例子,这是由于之前和之后的递归。

这很简单

情况就是这样:

mystery(n = 3):
    mystery(n = 2):
        mystery(n = 1):
            mystery(n = 0):
                n > 0 = false
            << done with mystery(n = 0)
            PRINT n * 4 = 4
            mystery(n = 0):
                n > 0 = false, this doesn't print anything
                << done with mystery(n = 0)
            << done with mystery(n = 1)
        PRINT n * 4 = 8 
        mystery(n = 1):
            mystery(n = 0):
                n > 0 = false, this doesn't print anything
                << done with mystery(n = 0)
            PRINT n * 4 = 4
            mystery(n = 0):
                n > 0 = false, this doesn't print anything
                << done with mystery(n = 0)
            << done with mystery(n = 1)
        << done with mystery(n = 2)
    PRINT n * 4 = 12
    mystery(n = 2):
        mystery(n = 1):
            mystery(n = 0):
                n > 0 = false, this doesn't print anything
                << done with mystery(n = 0)
            PRINT n * 4 = 4
            mystery(n = 0):
                n > 0 = false, this doesn't print anything
                << done with mystery(n = 0)
            << done with mystery(n = 1)
        PRINT n * 4 = 8 
        mystery(n = 1):
            mystery(n = 0):
                n > 0 = false, this doesn't print anything
                << done with mystery(n = 0)
            PRINT n * 4 = 4
            mystery(n = 0):
                n > 0 = false, this doesn't print anything
                << done with mystery(n = 0)
            << done with mystery(n = 1)
        << done with mystery(n = 2)
    << done with mystery(n = 3)
这很简单

情况就是这样:

mystery(n = 3):
    mystery(n = 2):
        mystery(n = 1):
            mystery(n = 0):
                n > 0 = false
            << done with mystery(n = 0)
            PRINT n * 4 = 4
            mystery(n = 0):
                n > 0 = false, this doesn't print anything
                << done with mystery(n = 0)
            << done with mystery(n = 1)
        PRINT n * 4 = 8 
        mystery(n = 1):
            mystery(n = 0):
                n > 0 = false, this doesn't print anything
                << done with mystery(n = 0)
            PRINT n * 4 = 4
            mystery(n = 0):
                n > 0 = false, this doesn't print anything
                << done with mystery(n = 0)
            << done with mystery(n = 1)
        << done with mystery(n = 2)
    PRINT n * 4 = 12
    mystery(n = 2):
        mystery(n = 1):
            mystery(n = 0):
                n > 0 = false, this doesn't print anything
                << done with mystery(n = 0)
            PRINT n * 4 = 4
            mystery(n = 0):
                n > 0 = false, this doesn't print anything
                << done with mystery(n = 0)
            << done with mystery(n = 1)
        PRINT n * 4 = 8 
        mystery(n = 1):
            mystery(n = 0):
                n > 0 = false, this doesn't print anything
                << done with mystery(n = 0)
            PRINT n * 4 = 4
            mystery(n = 0):
                n > 0 = false, this doesn't print anything
                << done with mystery(n = 0)
            << done with mystery(n = 1)
        << done with mystery(n = 2)
    << done with mystery(n = 3)

理解递归的诀窍是在imo中考虑不同的情况,而不是在精神上 跟踪调用图

神秘函数处理两种不同的情况:

n=<0:什么都不做

n>0:

做一些递归到n递减的事情,不在乎什么。 打印n*4 再次执行递归操作。 我们可以看到,这个函数唯一能做的就是打印一些数字。 对于n==3,我们得到可能是打印的东西12可能是打印的东西

现在,让我们用n==2和 我们得到

可能是印刷品8可能是印刷品12可能是印刷品8可能是印刷品

如果我们能记住基本情况,即当n==0i时,这个谜不起作用 当调用没有扩展多次时,认为调用的结构最明显。 你可以不断替换以确保你的答案是正确的,但是当你试图计算 一个递归函数做了什么?它通常只是伤害了我的大脑去思考
深入了解调用的确切内容。

理解递归的诀窍是在我看来考虑不同的情况,而不是在思想上 跟踪调用图

神秘函数处理两种不同的情况:

n=<0:什么都不做

n>0:

做一些递归到n递减的事情,不在乎什么。 打印n*4 再次执行递归操作。 我们可以看到,这个函数唯一能做的就是打印一些数字。 对于n==3,我们得到可能是打印的东西12可能是打印的东西

现在,让我们用n==2和 我们得到

可能是印刷品8可能是印刷品12可能是印刷品8可能是印刷品

如果我们能记住基本情况,即当n==0i时,这个谜不起作用 当调用没有扩展多次时,认为调用的结构最明显。 你可以不断替换以确保你的答案是正确的,但是当你试图计算 一个递归函数做了什么?它通常只是伤害了我的大脑去思考 深爱exac
您可以调试并理解在方法的开头和结尾添加更多的打印语句,如使用参数4输入,使用参数4退出,然后您就会看到。拿一张纸和一支铅笔,浏览所有神秘的调用。您可以随时调用递归方法函数,当存在递归停止条件时,您可以调试并理解在方法开始和结束时添加更多打印语句,如使用param 4输入,使用param 4退出,然后您就会看到。拿一张纸和一支铅笔,检查所有神秘调用。当存在递归停止条件n时,您可以随时调用递归方法函数