我正在做一个scala课程,其中一个例子是sumInts函数,定义如下:
def sumInts(a: Int, b: Int) : Int =
if(a > b) 0
else a + sumInts(a + 1 , b)
我试图通过在迭代时输出一些值来更好地理解这个函数:
class SumInts {
def sumInts(a: Int, b: Int) : Int =
if(a > b) 0 else
{
println(a + " + sumInts("+(a + 1)+" , "+b+")")
val res1 = sumInts(a + 1 , b)
val res2 = a
val res3 = res1 + res2
println("res1 is : "+res1+", res2 is "+res2+", res3 is "+res3)
res3
}
}
所以代码:
object SumIntsMain {
def main(args: Array[String]) {
println(new SumInts().sumInts(3 , 6));
}
}
返回输出:
3 + sumInts(4 , 6)
4 + sumInts(5 , 6)
5 + sumInts(6 , 6)
6 + sumInts(7 , 6)
res1 is : 0, res2 is 6, res3 is 6
res1 is : 6, res2 is 5, res3 is 11
res1 is : 11, res2 is 4, res3 is 15
res1 is : 15, res2 is 3, res3 is 18
18
有人可以解释如何计算这些值。我已经尝试输出所有创建的变量,但仍然很困惑。
答案 0 :(得分:6)
manual-human-tracer on:
return sumInts(3, 6) | a = 3, b = 6
3 > 6 ? NO
return 3 + sumInts(3 + 1, 6) | a = 4, b = 6
4 > 6 ? NO
return 3 + (4 + sumInts(4 + 1, 6)) | a = 5, b = 6
5 > 6 ? NO
return 3 + (4 + (5 + sumInts(5 + 1, 6))) | a = 6, b = 6
6 > 6 ? NO
return 3 + (4 + (5 + (6 + sumInts(6 + 1, 6)))) | a = 7, b = 6
7 > 6 ? YEEEEES (return 0)
return 3 + (4 + (5 + (6 + 0))) = return 18.
手动 - 人类追踪器关闭。
答案 1 :(得分:5)
要理解递归代码的作用,不必分析递归树。事实上,我认为这通常只是令人困惑。
让我们考虑一下我们要做的事情:我们希望将所有整数从a
开始求和,直到某个整数b
。
a + sumInts(a + 1,b)
让我们假装sumInts(a + 1, b)
实际上做了我们想要的事情:将整数从a + 1
求助到b
。如果我们接受这个是真理,很明显我们的函数会正确处理从a
到b
的更大问题。因为很明显,总和中缺少的是附加术语a
,只需添加即可。我们得出结论,它必须正常工作。
但是,这个sumInts()
必须建立在某种基础上:基本情况,不涉及递归。
if(a> b)0
仔细观察我们的递归调用,我们可以看到它做出了某些假设:我们希望a
低于b
。这意味着总和将如下所示:a + (a + 1) + ... + (b - 1) + b
。如果a
大于b
,则此总和自然会计算为0.
在递归调用保证中看到sumInts()
总是将a
增加1,我们实际上会在某个时刻触及基本情况。
进一步注意,最终将调用sumInts(b, b)
,我们现在可以验证代码是否有效:由于b
不大于自身,因此将调用第二种情况:b + sumInts(b + 1, b)
。从这里开始,很明显这将评估为:b + 0
,这意味着我们的算法可以正确地适用于所有值。
答案 2 :(得分:1)
您提到了替换模型,因此我们将其应用于您的sumInts
方法:
我们首先调用sumInts(3,4)
(你使用6作为第二个参数,但我选择了4,所以我可以输入更少),所以让我们用{代替{3}代替{4}代替a
1 {}在b
的定义中。这给了我们:
sumInts
那么,结果会是什么?好吧,if(3 > 4) 0
else 3 + sumInts(3 + 1, 4)
显然是假的,所以最终结果将等于else子句,即3加上3 > 4
的结果(4是sumInts(4, 4)
的结果)。现在我们需要知道3+1
的结果是什么。为此,我们可以再次替换(这次用4代替sumInts(4, 4)
和a
):
b
好的,if(4 > 4) 0
else 4 + sumInts(4 + 1, 4)
的结果将是4加sumInts(4,4)
的结果。那是什么sumInts(5,4)
?替换者!
sumInts(5,4)
这次if条件为真,所以if(5 > 4) 0
else 5 + sumInts(5 + 1, 4)
的结果为0.所以现在我们知道sumInts(5,4)
的结果必须是sumInts(4,4)
,这是4。 4 + 0
的结果必须为sumInts(3,4)
,即7。