方案R5RS,递归还是迭代?

时间:2015-01-26 00:16:21

标签: recursion scheme iteration

我编写了一个带有2个函数的方案代码,这些函数加上参数1,并从参数中减去1。我现在编写了一个自动执行此操作的函数,但我不知道它是递归还是迭代。这是完整的代码:

(define add1
     
  (lambda (x)
      
    (+ x 1)))

(define sub1
     
  (lambda (x)
    
    (- x 1)))

(define plus
    
  (lambda (x y)
    
    (if (zero? y)
    
        x
    
        (plus (add1 x) (sub1 y)))))

现在我的问题是,加上什么样的功能?递归,或迭代,为什么?

2 个答案:

答案 0 :(得分:5)

从句法上讲,plus函数是递归的:显然,它是自称的。有趣的问题是:它生成了什么样的进程?鉴于它是以tail-recursive方式编写的(直观地说:在递归调用之后没有什么可做的),我们可以声明它生成的过程是迭代的。有关过程及其生成过程的更详细讨论,请参阅SICP

答案 1 :(得分:0)

代码去了它是一个递归过程。然而,该过程是迭代的,因为它在尾部位置进行递归。

在Scheme中,您可以使用递归函数编写迭代和递归过程。

示例:

;; iterative process
;; recursive (inner) procedure
(define (fib n)
  (define (fib n a b)
    (if (zero? n)
        a
        (fib (- n 1) b (+ a b)))
  (fib n 0 1))

;; recursive process
;; recursive procedure
(define (fib n)
  (if (< n 2)
      n
      (+ (fib (- n 1))
         (fib (- n 2)))))

你也可以使用循环结构编写递归和迭代过程,但在Scheme中这样的循环结构实际上只是尾递归的语法糖。虽然为了能够更深入地进行处理,但在其他语言中这种情况相当普遍。

示例:

;; iterative process
;; iterative procedure  (do)
(define (fib n)
  (do ((n n (- n 1))
       (a 0 b)
       (b 1 (+ a b)))
      ((zero? n) a)))

;; recursive process
;; iterative procedure (do)
(define (fib n)
  (let ((work (list n #f)))
    ;; push x-1 and x-2 onto work
    (define (push-reduce! x)
      (set! work 
            (cons (- x 1) 
                  (cons (- x 2) work))))
    ;; pop top of work
    (define (pop)
      (let ((v (car work)))
        (set! work (cdr work))
        v))

    ;; find fibonacci with a iterative
    ;; (and ugly) do loop
    (do ((n 0 (if (< c 2) (+ n c) (begin (push-reduce! c) n)))
         (c (pop) (pop)))
      ((not c) n))))

最后一个是简单可怕的Scheme应该避免,但它几乎用于避免其他语言的堆栈溢出。