【问题标题】:Every procedure from recursive to iterative and vice versa?从递归到迭代的每个过程,反之亦然?
【发布时间】:2020-10-27 16:20:22
【问题描述】:

您能否将每个具有递归过程的递归过程从递归(甚至树递归)转换为迭代,反之亦然(在 Scheme 中)? 通过改变代码的编写方式?

【问题讨论】:

  • 为了清楚起见,请编辑添加更多字词。重复是可以的,损害清晰度的时尚英语是不行的。 “优雅的事情最好留给裁缝和鞋匠”,你知道的。
  • 但总的来说,如果我猜你问的是对的,是的。查找 CPS、去功能化、堆上的显式堆栈等。

标签: scheme lisp racket


【解决方案1】:

您必须区分递归函数/过程和递归过程。例如。想象一下走一棵二叉树。这肯定是一个递归过程,因为无论您如何实现它,您都需要回溯,因此如果您使其迭代,您将拥有某种数据结构来替换递归解决方案中使用的系统堆栈。

使用相同的算法,您无法将递归过程转换为迭代过程。这是不可能的。

但是,某些算法可能会被执行其他操作的其他算法所取代。斐波那契过程就是一个很好的例子。这是一个tree walk版本:

(define (fib-rec n)
  (if (< n 2)
      n
      (+ (fib-rec (- n 1)) 
         (fib-rec (- n 2)))))

你可能已经看过这个版本,它的算法只是从底部到答案迭代一个值的窗口:

(define (fib-iter n)
  (let loop ((n n) (a 0) (b 1))
    (if (zero? n)
        a
        (loop (- n 1) b (+ a b)))))

这些不是同一个算法。 fib-rec 的递归到迭代转换将是这样的:

(define (fib n)
  (let loop ((jobs '(fib)) (args (list n)))
    (cond ((null? jobs)
           (car args))
          ((eq? (car jobs) 'swap)
           (loop (cdr jobs)
                 (list* (cadr args) (car args) (cddr args))))
          ((eq? (car jobs) 'add)
           (loop (cdr jobs)
                 (cons (+ (car args)
                          (cadr args))
                       (cddr args))))
          ((< (car args) 2) 
           (loop (cdr jobs) args))
          (else 
           (loop (list* 'fib 'swap 'fib 'add (cdr jobs))
                 (list* (- (car args) 2) (- (car args) 1) (cdr args)))))))

这与fib-rec 几乎相同,只是它使用操作列表和参数堆栈。这是一个递归过程,但过程是尾递归的,因此是迭代的。

如果不更改算法,则无法将继承的迭代过程转换为递归过程。将其视为拥有fib-iter 并将其重写为fib-rec。此外,由于 Scheme 除了递归之外没有原始循环结构,所有迭代过程都是通过递归完成的。如果您阅读报告,您会看到do 和其他循环构造是派生语法以及它们变成什么递归。

【讨论】:

    【解决方案2】:

    是的,当然。 递归函数总是有一个中断条件。 有时,中断条件是关于一个已用完的列表,因此从递归调用到下一个递归调用变为空。 在这种情况下,您可以通过列表上的 for 循环来处理它。 有时,中断条件是一些数字减少或其他 - 然后可以使用 while 循环来测试中断条件。

    【讨论】:

    • 谢谢。从迭代到递归?
    • 好吧,如果迭代超过了一个用完的循环或达到某个阈值的计数器,则可以设置递归的中断条件,以测试是否达到限制(= 限制计数器)或列表末尾 (null lst)。并且在通过计数步骤或(cdr lst) 调用下一个递归调用 dlminish/enhance 计数器时。
    • 如果迭代是while循环,则while中断条件变为递归中断条件。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-06-19
    • 2011-10-29
    • 2019-02-10
    • 2013-12-31
    • 2014-11-08
    相关资源
    最近更新 更多