【问题标题】:Tail-recursive?尾递归?
【发布时间】:2011-09-11 17:29:47
【问题描述】:

我正在编写一个函数,它接受一个列表并返回列表中所有项目的平方和。调用 (1 2 3) 它应该返回 14: (12 + 22 + 32)。

我有这个 sqsum 函数:

(define (sqsum lis)
    (if (null? lis)
        0
        (+ (* (car lis) (car lis)) (sqsum (cdr lis)))
    )
)

这个尾部是递归的吗?我认为它是递归的,但不是尾递归的。 这是我作业的一部分,我不是在寻找解决方案:我只想知道这是否是尾递归。如果没有,那么我需要阅读更多内容并找到新的解决方案。

【问题讨论】:

  • 问问自己这个函数在返回之前的最后一个操作是什么——是调用sqsum还是+?

标签: function scheme tail-recursion


【解决方案1】:

要成为尾递归,递归必须发生在最后一个函数,即你不能对 recursiv 调用的结果做任何事情。在这里,您将它传递给 +,这使它成为非尾递归的。不过编译器可以优化掉它,而且自己也很容易做到。

【讨论】:

【解决方案2】:

不,它不是尾递归。

使非尾递归函数尾递归的一般方法是包含一个累加器,它是一个额外的参数,通过递归调用携带过程的当前评估。

顺便说一句,这也是“帮助”函数非常有用的地方。一般的做法是定义你的函数,使其使用累加器,在其中定义一个确实使用累加器的辅助函数,然后让主函数使用除了调用辅助函数之外几乎没有。你马上就会明白我的意思。

在你的情况下(如果我正确地记住了我的方案:p):

(define (sqsum lis)
    (define (sqsum-h lis acc)
        (if (null? lis)
            acc
            (sqsum-h (cdr lis) (+ acc (* (car lis) (car lis))))
        )
    )
    (sqsum-h lis 0)
)

这是尾递归,因为任何递归调用所做的最后一件事就是立即返回另一个函数的结果而不修改它。

【讨论】:

    猜你喜欢
    • 2016-03-21
    • 2018-03-17
    • 1970-01-01
    • 2017-11-11
    • 1970-01-01
    • 2019-10-30
    • 2011-03-03
    • 2011-11-14
    • 1970-01-01
    相关资源
    最近更新 更多