微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

每个递归都可以转换成迭代吗?

如何解决每个递归都可以转换成迭代吗?

你总能把递归函数变成迭代函数吗?是的,绝对是,如果有记忆的话,Church-Turing 论文就证明了这一点。通俗地说,它指出可以通过递归函数计算的内容可以通过迭代模型(例如图灵机)计算,反之亦然。论文并没有准确地告诉你如何进行转换,但它确实说这绝对是可能的。

在许多情况下,转换递归函数很容易。knuth 在“计算机编程的艺术”中提供了几种技术。通常,递归计算的事物可以通过完全不同的方法在更少的时间和空间内进行计算。典型的例子是斐波那契数列或数列。你肯定在你的学位计划中遇到过这个问题。

在这枚硬币的另一面,我们当然可以想象一个编程系统如此先进,以至于将公式的递归定义视为记忆先前结果的邀请,从而提供速度优势,而无需麻烦告诉计算机确切的步骤遵循具有递归定义的公式的计算。Dijkstra 几乎可以肯定地想象过这样一个系统。他花了很长时间试图将实现与编程语言的语义分开。再一次,他的非确定性和多处理编程语言在实践中的专业程序员之上。

归根结底,许多函数以递归形式更易于理解、阅读和编写。除非有令人信服的理由,否则您可能不应该(手动)将这些函数转换为显式迭代算法。您的计算机将正确处理该作业。

我可以看到一个令人信服的理由。假设您有一个使用超高级语言的原型系统,例如 Scheme、Lisp、Haskell、OCaml、Perl 或 Pascal。假设条件是您需要用 C 或 Java 实现。(也许这是政治问题。)然后你当然可以递归地编写一些函数,但如果按字面意思翻译,它们会炸毁你的运行时系统。例如,无限尾递归在 Scheme 中是可能的,但同样的习惯用法会给现有的 C 环境带来问题。另一个例子是使用词法嵌套函数和静态作用域,Pascal 支持但 C 不支持

在这种情况下,您可能会尝试克服对原始语言的政治阻力。你可能会发现自己重新实现 Lisp 很糟糕,就像在 Greenspun 的(开玩笑的)第十定律中一样。或者您可能会找到一种完全不同的解决方案。但无论如何,肯定有办法的。

解决方法

一个reddit
线程
提出了一个明显有趣的问题:

尾递归函数可以很容易地转换为迭代函数。其他的,可以通过使用显式堆栈进行转换。 每个 递归都可以转化为迭代吗?

帖子中的(反?)示例是一对:

(define (num-ways x y)
  (case ((= x 0) 1)
        ((= y 0) 1)
        (num-ways2 x y) ))

(define (num-ways2 x y)
  (+ (num-ways (- x 1) y)
     (num-ways x (- y 1))

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。