我学习递归,并且有一个例子,我解决了写一些*字符的问题。
例如:如果你要传递数字3,它应该打印2 ^ 3星,这样就会打印出8颗星。
我应该打印2 ^ k次,其中k是传递的整数。这个问题的答案是:
public String printStars(int k) {
if (k == 0)
return "*";
else
return printStars(k - 1) + printStars(k - 1);
}
我似乎无法理解调用堆栈以及如何解决问题,我查看它的方式,当我为int k传入3时,它将执行n - 1 3次直到它击中基本情况,并且在此之前返回2星级的电话,并且由于它需要3个级别来获得深度,它将打印3 x 2星,因此它将打印6颗星。这很奇怪,因为大多数其他递归对我来说很容易,但这很令人困惑。
答案 0 :(得分:1)
我想它必须始终是k
或n
?
递归如何工作:它跨越一棵树:
每次调用printStars都会导致一个*
(2 ^ 0)或两个*
(2 ^ 1)。
如果你打电话给printStars(4):
递归级别4 ist!= 0因此它返回两次单独调用的收缩,每次调用都带有参数(3)。
递归级别3 ist!= 0因此它返回两次单独调用的收缩,每次调用都带有参数(2)。
递归级别2 ist!= 0因此它返回两次单独调用的收缩,每次调用都带有参数(1)。
递归级别1 ist!= 0因此它返回两次单独调用的收缩,每次调用都带有参数(0)。
递归级别0 ist == 0因此每次调用返回一个*
。
返回递归级别1,我们收到两个*
并签约并返回它们。
返回递归级别2,我们收到两个**
并收缩并返回它们。
回到递归级别3,我们收到两个****
并签约并返回它们。
回到递归级别4,我们收到两个********
并签约并返回它们。
所以来电者收到'***************'2 ^ 4 = 16 *'
caller |
k=4 / \ (just call yourself 2 times an return contraction of both calls)
k=3 / \ / \ (just call yourself 2 times an return contraction of both calls)
k=2 / \ / \ / \ / \ (just call yourself 2 times an return contraction of both calls)
k=1 /\ /\ /\ /\ /\ /\ /\ /\ (just call yourself 2 times an return contraction of both calls)
k=0 ** ** ** ** ** ** ** ** (just return 2^0 = 1 '*')
答案 1 :(得分:0)
只需按照以下代码操作:
应该清楚的是,在非基本情况下:
printStars(k).length() == 2 * printStars(k - 1).length()
因为那种情况下的值由
给出return printStars(k - 1) + printStars(k - 1);
使用这种观察,我们可以通过归纳证明:
printStars(k).length() == 2^k
(其中^
表示幂,而不是按位XOR)
printStars(0).length() == 2^0
printStars(k - 1).length() == 2^(k-1)
,printStars(k).length() == 2 * printStars(k - 1).length() == 2^k
QED。
答案 2 :(得分:0)
我认为简单的方法就是扩展每个函数调用:
当k = 3时,return
语句的计算结果为printStars(2) + printStars(2)
。
所以它会首先调用左边的printStars(2)
,它将评估为:
printStars(1) + printStars(1) + printStars(2)
再次,让我们先展开左边的一个:
printStars(0) + printStars(0) + printStars(1) + printStars(2)
printStars(0)
最终将评估为"*"
,因此我们有
"*" + "*" + printStars(1) + printStars(2)
== "**" + printStars(1) + printStars(2)
。
我们已经看到了printStars(1) == "**"
所以我们有:
"****" + printStars(2)
。我们已经知道printStars(2)
将解决的问题。