SICP中使用迭代过程的斐波那契数列,不能完全理解

fibonacci sequence using iterative process in SICP, cannot completely understand

这是在 SICP 中计算斐波那契数列的过程的迭代示例。思路是:

(define (fib n) 
  (fib-iter 1 0 n))
(define (fib-iter a b count)
  (if (= count 0)
      b
      (fib-iter (+ a b) a (- count 1))))

深入观察,我不明白为什么需要继续计算 fib(n+1) 。我发现我们可以写。

;; a and b are first and second integers respectively
;; in the recursive call, b would be replaced by a+b because it is the next number in the sequence
;; so now a will be replaced by the previous value of b because it is the previous value.
(define (fib2 n) 
  (fib-iter 1 0 n))
(define (fib-iter a b count)
  (if (= count 0)
      b
      (fib-iter b (+ a b) (- count 1))))

现在,我真的觉得第一个例子,一直到 n+1 的例子真的是多余的。我不明白为什么这是必要的。我提出的迭代示例有什么问题?

没有错。两种方法给出相同的结果。

#lang racket
(define (fib n) 
  (fib-iter 1 0 n))
(define (fib-iter a b count)
  (if (= count 0)
      b
      (fib-iter (+ a b) a (- count 1))))

(define (fib2 n) 
  (fib-iter2 1 0 n))

(define (fib-iter2 a b count)
  (if (= count 0)
      b
      (fib-iter2 b (+ a b) (- count 1))))

(define xs '(0 1 2 3 4 5 6 7 8 9 10))
(map fib  xs)
(map fib2 xs)

输出为:

'(0 1 1 2 3 5 8 13 21 34 55)
'(0 1 1 2 3 5 8 13 21 34 55)

这表明你确实在计算相同的序列。

机器人程序产生正确的结果。但是,第一个保留了 ab 之间的关系: aFib(i+1) 并且 bFib(i) 其中 i=n-count .第二种方法使用第一次迭代来交换 ab ,从而引入一个冗余迭代。这可以通过跟踪程序看出:

> (define (fib n) 
  (fib-iter 1 0 n))

(define (fib-iter a b count)
  (if (= count 0)
      b
      (fib-iter (+ a b) a (- count 1))))
> (trace fib-iter)
> (fib 3)
>(fib-iter 1 0 3)
>(fib-iter 1 1 2)
>(fib-iter 2 1 1)
>(fib-iter 3 2 0)
<2
2
> (define (fib-iter a b count)
  (if (= count 0)
      b
      (fib-iter b (+ a b) (- count 1))))
> (trace fib-iter)
> (fib 3)
>(fib-iter 1 0 3)
>(fib-iter 0 1 2)
>(fib-iter 1 1 1)
>(fib-iter 1 2 0)
<2
2

你真正想要的是这样的:

> (define (fib n)
  (if (zero? n)
      0
      (fib-iter 0 1 (- n 1))))

(define (fib-iter a b count)
  (if (zero? count)
      b
      (fib-iter b (+ a b) (- count 1))))

> (trace fib-iter)
> (fib 3)
>(fib-iter 0 1 2)
>(fib-iter 1 1 1)
>(fib-iter 1 2 0)
<2
2

注意,少了一次迭代。但是,我在 fib.

过程中做了额外的工作