简体   繁体   English

Java帮助中的递归

[英]Recursion in java help

I am new to the site and am not familiar with how and where to post so please excuse me. 我是该网站的新手,不熟悉发布方式和发布地点,请原谅。 I am currently studying recursion and am having trouble understanding the output of this program. 我目前正在研究递归,并且无法理解该程序的输出。 Below is the method body. 下面是方法主体。

public static int Asterisk(int n)
{
if (n<1)
return;

Asterisk(n-1);

  for (int i = 0; i<n; i++)
  {
      System.out.print("*");
  }
  System.out.println();
} 

This is the output 这是输出

 *
 **
 ***
 ****
 *****

it is due to the fact that the "Asterisk(n-1)" lies before the for loop. 这是因为“ Asterisk(n-1)”位于for循环之前。

I would think that the output should be 我认为输出应该是

****
***
**
*

This is the way head recursion works. 这是头部递归的工作方式。 The call to the function is made before execution of other statements. 该函数的调用在执行其他语句之前进行。 So, Asterisk(5) calls Asterisk(4) before doing anything else. 因此,Asterisk(5)在执行其他任何操作之前先调用Asterisk(4)。 This further cascades into serial function calls from Asterisk(3) → Asterisk(2) → Asterisk(1) → Asterisk(0). 这进一步从Asterisk(3)→Asterisk(2)→Asterisk(1)→Asterisk(0)级联为串行函数调用。

Now, Asterisk(0) simply returns as it passes the condition n<1 . 现在,Asterisk(0)在通过条件n<1简单地返回。 The control goes back to Asterisk(1) which now executes the rest of its code by printing n=1 stars. 控件返回到Asterisk(1),现在通过打印n = 1个星号来执行其余代码。 Then it relinquishes control to Asterisk(2) which again prints n=2 stars, and so on. 然后将控制权交给Asterisk(2),它再次打印n = 2星,依此类推。 Finally, Asterisk(5) prints its n=5 stars and the function calls end. 最后,Asterisk(5)打印n = 5星,函数调用结束。 This is why you see the pattern of ascending number of stars. 这就是为什么您看到星数递增的模式的原因。

There are two ways to create programming loops. 有两种创建编程循环的方法。 One is using imperative loops normally native to the language (for, while, etc) and the other is using functions (functional loops). 一种是使用通常是语言固有的命令式循环(for,while等),另一种是使用函数(功能循环)。 In your example the two kinds of loops are presented. 在您的示例中,展示了两种循环。

One loop is the unrolling of the function 一个循环是功能的展开

Asterisk(int n)

This unrolling uses recursion, where the function calls itself. 此展开使用递归,在递归函数本身。 Every functional loop must know when to stop, otherwise it goes on forever and blows up the stack. 每个功能循环都必须知道何时停止,否则它将永远持续下去并炸毁堆栈。 This is called the "stopping condition". 这称为“停止条件”。 In your case it is : 您的情况是:

if (n<1)
return;

There is bidirectional equivalence between functional loops and imperative loops (for, while, etc). 功能循环和命令式循环(for,while等)之间存在双向等价关系。 You can turn any functional loop into a regular loop and vice versa. 您可以将任何功能循环变成常规循环,反之亦然。

IMO this particular exercise was meant to show you the two different ways to build loops. IMO的这一特殊练习旨在向您展示构建循环的两种不同方式。 The outer loop is functional (you could substitute it for a for loop) and the inner loop is imperative. 外循环是功能性的(可以用for循环代替),而内循环则势在必行。

Think of recursive calls in terms of a stack. 考虑堆栈的递归调用。 A stack is a data structure which adds to the top of a pile. 堆栈是添加到堆栈顶部的数据结构。 A real world analogy is a pile of dishes where the newest dish goes on the top. 真实世界的比喻是一堆菜,最新的菜排在最前面。 Therefore recursive calls add another layer to the top of the stack, then once some criteria is met which prevents further recursive calls, the stack starts to unwind and we work our way back down to the original item (the first plate in pile of dishes). 因此,递归调用将另一层添加到堆栈的顶部,然后,一旦满足某些条件(阻止进一步的递归调用),则堆栈开始展开,然后我们回到原始项目(一堆菜中的第一盘) 。

The input of a recursive method tends towards a base case which is the termination factor and prevents the method from calling itself indefinitely (infinite loop). 递归方法的输入趋向于作为终止因子基本情况 ,并防止该方法无限期地调用自身(无限循环)。 Once this base condition is met the method returns a value rather than calling itself again. 一旦满足此基本条件,该方法将返回一个值,而不是再次调用自身。 This is how the stack in unwound. 这就是堆栈展开的方式。

In your method, the base case is when $n<1$ and the recursive calls use the input $n-1$. 在您的方法中,基本情况是$ n <1 $并且递归调用使用输入$ n-1 $。 This means the method will call itself, each time decreasing $n$ by 1, until $n<1$ ie $n=0$. 这意味着该方法将自行调用,每次将$ n $减1,直到$ n <1 $,即$ n = 0 $。 Once the base condition is met, the value 0 is returned and we start to execute the $for$ loop. 满足基本条件后,将返回值0,我们开始执行$ for $循环。 This is why the first line contains a single asterix. 这就是第一行包含单个星号的原因。

So if you run the method with an input of 5, the recursive calls build a stack of values of $n$ as so 因此,如果您在输入为5的情况下运行该方法,则递归调用将构建$ n $值的堆栈

0
1
2
3
4
5

Then this stack is unwound starting with the top, 0, all the way down to 5. 然后,从顶部的0开始一直向下展开堆栈,以展开此堆栈。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM