这是计算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的例子真的是多余的。我不明白为什么这是必要的。我提出的迭代示例有什么问题?
答案 0 :(得分: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)
这表明您确实在计算相同的序列。
答案 1 :(得分:1)
Bot程序产生正确的结果。但是,第一个保留a
和b
之间的关系:a
为Fib(i+1)
,b
为Fib(i)
,其中i=n-count
。第二种方法使用第一次迭代来交换a
和b
,从而引入一个冗余迭代。通过以下程序可以看出这一点:
> (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
中做了额外的工作。