我在算法书中读到Ackermann函数不能被做成尾递归(他们说的“它不能被转换成迭代”)。我很困惑这个,所以我试图想出这个:这个实现是否是递归的
let Ackb m n =
let rec rAck cont m n =
match (m, n) with
| 0, n -> cont (n+1)
| m, 0 -> rAck cont (m-1) 1
| m, n -> rAck (fun x -> rAck cont (m-1) x) m (n-1)
in rAck (fun x -> x) m n
;;
(这是OCaml/F#代码)。
我的问题是,我不确定这实际上是尾递归。你能确认它是什么吗?如果不是,为什么?最终,当人们说阿克曼函数不是原始递归时,这意味着什么?
谢谢!
当您传递该lambda表达式时,您仍然在构建函数调用的“堆栈”。 – 2010-12-12 22:47:22
是的,它是尾递归的。你可以用'-dlinear'选项用ocamlopt编译文件。这应该可以帮助您确定您的功能是否使用尾部呼叫。 – nlucaroni 2010-12-13 16:36:11