使用递归计算要打印的东西的数量
Posted
技术标签:
【中文标题】使用递归计算要打印的东西的数量【英文标题】:Using Recursion to compute the number of something to print 【发布时间】:2016-03-15 01:52:17 【问题描述】:我学习递归,有一个例子可以解决写 * 字符一定次数的问题。
例如:如果你要传入数字 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 颗星。这很奇怪,因为大多数其他递归对我来说很容易,但这很令人困惑。
【问题讨论】:
我假设您的意思是k
而不是 n
(反之亦然)。
【参考方案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 *'s
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 '*')
【讨论】:
很棒的图表,感谢您的回复,使过程非常清晰,感谢您的宝贵时间!【参考方案2】:我认为查看它的简单方法是扩展每个函数调用:
当 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)
会解决什么问题。
【讨论】:
谢谢,我一直在关注它,但忘记了需要将 printStars(#) 的原始调用添加到您递归的内容中。所以我得到的答案是正确的答案——你从最初的电话中得到的。谢谢你这么解释【参考方案3】:只需按照代码进行操作:
应该清楚的是,在非基本情况下:
printStars(k).length() == 2 * printStars(k - 1).length()
因为这种情况下的值由下式给出
return printStars(k - 1) + printStars(k - 1);
使用这个观察,我们可以通过归纳证明:
printStars(k).length() == 2^k
(其中^
表示幂,而不是按位异或)
printStars(0).length() == 2^0
的基本情况下是真的
假设printStars(k - 1).length() == 2^(k-1)
,printStars(k).length() == 2 * printStars(k - 1).length() == 2^k
QED。
【讨论】:
感谢您的解释,非常有帮助!以上是关于使用递归计算要打印的东西的数量的主要内容,如果未能解决你的问题,请参考以下文章
如何使用递归函数计算和打印以下序列的前 N 个元素的总和
左神算法第八节课:介绍递归和动态规划(汉诺塔问题;打印字符串的全部子序列含空;打印字符串的全排列,无重复排列;母牛数量;递归栈;数组的最小路径和;数组累加和问题,一定条件下最大值问题(01背包))