用sumInts方法理解scala替代模型

用sumInts方法理解scala替代模型,scala,recursion,Scala,Recursion,我正在学习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

我正在学习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

有人能解释一下这些值是如何计算的吗。我尝试输出所有创建的变量,但仍然感到困惑。

您提到了替代模型,因此让我们将其应用到您的
sumInts
方法:

我们首先调用
sumInts(3,4)
(您使用了6作为第二个参数,但我选择了4,因此我可以少键入),因此让我们在
sumInts
的定义中用3代替
a
,用4代替
b
。这给了我们:

if(3 > 4) 0  
else 3 + sumInts(3 + 1, 4)
那么,结果会是什么呢?那么,
3>4
显然是错误的,因此最终结果将等于else子句,即3加上
sumInts(4,4)
(4是
3+1
的结果)。现在我们需要知道
sumInts(4,4)
的结果是什么。为此,我们可以再次替换(这次用4替换
a
b
):

好的,
sumInts(4,4)
的结果将是4加上
sumInts(5,4)
的结果。那么什么是sumInts(5,4)?给替换者

if(5 > 4) 0
else 5 + sumInts(5 + 1, 4)

这次if条件为true,因此
sumInts(5,4)
的结果为0。现在我们知道,sumInts(4,4)的结果必须是
4+0,也就是4。因此,
sumInts(3,4)
的结果必须是
3+4
,即7。

手动人体跟踪器:

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.

手动跟踪关闭。

要了解递归代码的功能,无需分析递归树。事实上,我认为这常常令人困惑

假装有用 让我们考虑一下我们要做的事情:我们想对从
a
到某个整数
b
的所有整数求和

a+消费(a+1,b)

让我们假设
sumInts(a+1,b)
实际上实现了我们想要的:将
a+1
b
的整数相加。如果我们接受这一事实,很明显,我们的函数将正确地处理更大的问题,从
a
b
。因为很明显,总和中缺少的只是一个附加项
a
,它只是简单地加上。我们的结论是,它必须正确工作

基础:基本情况 但是,这个
sumInts()
必须建立在一些基础之上:基本情况,其中不涉及递归

如果(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
,这意味着我们的算法对所有值都能正确工作。

我认为您为main发布了错误的代码。您的main方法甚至不调用sumits方法。@sepp2k抱歉,我已经更新了问题让我们试试更简单的方法:
def sumTo(n:Int):Int=if(n@Rex Kerr,谢谢,但我不是在寻找一个更简单的算法来处理发布的算法。@user701254-如果你不能理解那些打印输出的更难的算法,那么你应该尝试一个更简单的模拟来发展你思考递归的能力。
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.