我是网站新手,不熟悉发布方式和地点,请原谅。我目前正在研究递归,并且无法理解该程序的输出。以下是方法体。
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();
}
这是输出
*
**
***
****
*****
这是因为&#34; Asterisk(n-1)&#34;位于for循环之前。
我认为输出应该是
****
***
**
*
答案 0 :(得分:2)
这是头递归的工作方式。在执行其他语句之前调用该函数。因此,Asterisk(5)在做任何其他事情之前都会调用Asterisk(4)。这进一步级联为Asterisk(3)→Asterisk(2)→Asterisk(1)→Asterisk(0)的串行函数调用。
现在,Asterisk(0)只是在通过条件n<1
时返回。控件返回到Asterisk(1),它现在通过打印n = 1星来执行其余的代码。然后它放弃对Asterisk(2)的控制,再次打印n = 2星,依此类推。最后,Asterisk(5)打印出n = 5星,函数调用结束。这就是为什么你会看到升星数量的模式。
答案 1 :(得分:0)
有两种方法可以创建编程循环。一种是使用通常为语言原生的命令式循环(for,while等),另一种是使用函数(函数循环)。在您的示例中,显示了两种循环。
一个循环是展开函数
Asterisk(int n)
此展开使用递归,函数调用自身。每个功能循环必须知道何时停止,否则它将永远持续并炸毁堆栈。这被称为&#34;停止条件&#34;。在你的情况下它是:
if (n<1)
return;
功能循环和命令循环之间存在双向等价(for,while等)。您可以将任何功能循环转换为常规循环,反之亦然。
IMO这个特殊的练习旨在向您展示构建循环的两种不同方法。外循环是功能性的(你可以用它代替for循环),内循环是必要的。
答案 2 :(得分:0)
考虑堆栈方面的递归调用。堆栈是添加到堆栈顶部的数据结构。一个现实世界的比喻是一堆菜肴,其中最新的菜肴在顶部。因此,递归调用会在堆栈顶部添加另一个层,然后一旦满足一些条件就会阻止进一步的递归调用,堆栈就会开始展开,然后我们回到原始项目(堆栈中的第一个盘子)
递归方法的输入倾向于基本情况,它是终止因子并阻止该方法无限期地调用自身(无限循环)。一旦满足此基本条件,该方法将返回一个值,而不是再次调用自身。这是堆栈解开的方式。
在你的方法中,基本情况是$ n&lt; 1 $,递归调用使用输入$ n-1 $。这意味着该方法将自己调用,每次将$ n $减少1,直到$ n <1 $,即$ n = 0 $。一旦满足基本条件,返回值0,我们开始执行$ for $循环。这就是第一行包含单个星号的原因。
因此,如果您使用输入5运行该方法,则递归调用会构建一堆$ n $的值,因此
0
1
2
3
4
5
然后这个堆栈从顶部0开始解开,一直到5。