【问题标题】:Are tail recursion and dynamic programming the same?尾递归和动态规划是一样的吗?
【发布时间】:2012-09-20 22:14:15
【问题描述】:

我正在使用尾递归对斐波那契数进行编程,它背后的想法似乎与动态编程相同。那么它们是一样的吗?或者更确切地说,它们之间有一些相似之处?如果不是,它们何时会有所不同?

【问题讨论】:

    标签: dynamic-programming tail-recursion


    【解决方案1】:

    动态编程通常是一种更有效的方法来完成与尾递归相同的任务。主要区别在于动态编程存储已经计算的结果,因此如果出现相同的操作,而不是再次运行代码,只需查找该值。这会占用更多空间/内存,但会产生更快的算法。

    在斐波那契的情况下,动态编程解决方案是不断添加数组中的最后两个元素以获得下一个元素。尾递归解决方案将从头开始计算斐波那契的每个值。

    【讨论】:

    • 这个答案似乎暗示可以用动态规划来代替尾递归;这真的不是真的,因为尾递归(和尾递归优化)是非常重要的实现技术,在函数式编程中应用得更广泛。
    【解决方案2】:

    我明白你为什么要问这个问题。动态规划背后的想法是将问题分解为更小的问题,这与许多递归(尾或非尾)函数背后的想法完全相同。

    这确实是一种苹果与橘子的比较,有很多很好的答案,但有一件事让你意识到为什么很难比较这两个想法:在某些语言中,包括 Java,技术上你不能使用尾递归。您可能知道,尾递归函数不会存储其调用的结果堆栈并在以后使用它们。然而,在 Java 中,为每个方法调用维护一个堆栈跟踪。这会使用堆栈空间,如果运行次数过多,可能会出现堆栈溢出。因此,任何看起来可能是尾递归的 Java 方法实际上都不是。

    【讨论】:

    • 可以(在技术上和非技术上)在 Java 中使用尾递归;这很危险,而且是个坏主意。
    【解决方案3】:

    这些术语本身虽然相关,但无论如何都不等同:

    • 动态编程是一种解决问题的方法,可以使用或不使用尾递归来实现。更一般地说,它需要“记忆”。

    • 尾递归是实现动态规划算法的常用方法,因为它专门将记忆逻辑应用于特定字段。

    【讨论】:

    • 尾递归如何“专门将[y]记忆逻辑应用于特定字段”?
    • 好吧,当你tail recur时,你只是发送最后一个计算的值,而不是用一堆还没有执行的函数调用来填充堆栈。这与循环构造中的记忆相同,一遍又一遍地重新绑定变量。
    猜你喜欢
    • 2013-10-09
    • 1970-01-01
    • 2014-05-22
    • 2020-11-20
    • 1970-01-01
    • 2014-06-26
    • 2013-11-14
    • 2012-07-10
    • 2011-11-09
    相关资源
    最近更新 更多