我编写了一个带有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)))))
现在我的问题是,加上什么样的功能?递归,或迭代,为什么?
答案 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应该避免,但它几乎用于避免其他语言的堆栈溢出。