【问题标题】:Tricky recursive (tail) function examples棘手的递归(尾)函数示例
【发布时间】:2017-03-25 12:16:13
【问题描述】:

我从不喜欢玩弄定义,尤其是在面试时。 据我所知:

编辑:

尾递归函数是在递归调用后不再进行任何计算的函数。

我认为第二个不是尾递归,因为它根本不进行递归调用,因此不是尾递归。

但是第一个是尾递归的,即使它进行了 2 次递归调用,之后它也没有做任何事情,所以我想我在这里正确使用了尾递归的定义。

let rec func x =
    if x > 10 then x else func (func (x+1))  

let f a b = a + b

【问题讨论】:

  • 请标记语言。
  • 请再看我的回答,我已经更正了
  • 内部 func 调用不在尾部位置,因此 func 不是尾部递归
  • 一个更少的格式定义是尾递归可以表示为goto。在func (func (x+1)) 中,内部func 不能作为goto 完成,而外部可以。请注意,在 f 中没有递归,但您有一个尾调用。 a + b 可以表示为转到+ 函数。

标签: ocaml tail-recursion


【解决方案1】:

您对递归函数的定义是tail 递归函数。递归函数被简单地定义为在其执行的某个时刻调用自身的函数。该定义还允许间接递归的函数,即它们调用另一个函数,该函数再次调用原始函数(此链可以是任意长度)。

您认为您的第二个函数根本不是递归的,这是对的。但是,第一个函数不是尾递归的。

如果我们将这个函数移到 Scala 中,我们会得到;

@tailrec
def func(x: Int): Int = 
{
    if (x > 10) x
    else func(func(x+1))
}

@tailrec 注释告诉我们某些东西是否是尾递归的。但是,编译器通知我们有一个不在尾部位置的递归调用。即,两个调用的内部。尾递归函数要求对函​​数的所有调用都在尾部位置,而不仅仅是最终调用处于尾部位置

【讨论】:

  • 是的,我忘了在我的句子中添加尾递归 :)
  • 除了第一个函数不是tail rec.
  • @Drup 好吧,我在 Scala 中验证你是正确的......我会调整我的答案
  • 你不需要接触 Scala,它是一个简单的语法标准,很容易看到,如果你需要帮助,可以在 OCaml 中找到[@tailcall]
猜你喜欢
  • 2011-03-15
  • 1970-01-01
  • 2019-09-14
  • 1970-01-01
  • 1970-01-01
  • 2012-12-28
  • 2016-12-20
  • 1970-01-01
  • 2016-06-13
相关资源
最近更新 更多