首页 > 解决方案 > 斐波那契数列迭代?

问题描述

我是新来的球拍并试图给一个函数一个整数,它应该返回它的斐波那契值(迭代地)。我不知道我做错了什么,如果我合并一个 if 语句来捕捉当 number = 1 一切都坏了

(define (fib-iterat n)
 (do ((i 1 (+ i 1))
   (nextTerm 0 (+ value0 value1))
   (value0 0 (+ value1 0))
   (value1 1 (+ nextTerm 0)))
((> i n) nextTerm))
)

我得到:

1 = 1
2 = 1
6 = 3
9 = 7
12 = 16

标签: racket

解决方案


;;; correct
(define (fib n)
  (do ((i 0 (+ i 1))
       (n1 1 (+ n0 n1))
       (n0 0 n1))
    ((= i n) n0)))

;;; still correct
(define (fib n)
    (do ((i 0 (+ i 1))
         (n0 0 n1)
         (n1 1 (+ n0 n1)))
      ((= i n) n0)))


;;; wrong
(define (fib-iterat n)
  (do ((i 0 (+ i 1))
       (value1 1 nextTerm)
       (value0 0 value1)
       (nextTerm 1 (+ value0 value1))) ; first bracket close
    ((= i n) (list value0 value1 nextTerm)))) ; second bracket

我从来没有读过任何“do loop”代码(但它应该很容易理解)。你可以这样想。我们将旧状态和新状态分开。在第一个括号变量演算中,仅使用旧状态值。因此,在许多情况下,do 循环中的第一个括号顺序应该是无关紧要的。我们刷新变量值,但新值将在下一个循环或第二个括号中使用。

尝试(fib-iterat 2),我们称旧状态(o1,o2,o3),i=0≠n,旧状态:none,新状态:(value0,value1,nextTerm)=(0,1,1),我=我+1

i=1≠n,旧状态:(0,1,1),新状态:(o2,o3,o2+o3)=(1,1,1),i=i+1

i=2=n, old state:(1,1,1), new state:(o2,o3,o2+o3)=(1,1,2) 我们想要 (1,2,2) 所以它错了。

我认为最重要的是不要认为它是一套!捆绑。更像是这样。

(define (f n)
  (do ([i 0 (+ i 1)]
       [n1 1 (+ n1 n3)]
       [n2 1 (+ n1 n2)]
       [n3 1 (+ n2 n3)])
    ((= i n) (list n1 n2 n3))))

(define (my-do-loop  n)
  (local ((define (λ0 i n1 n2 n3) (+ i 1))
          (define (λ1 i n1 n2 n3) (+ n1 n3))
          (define (λ2 i n1 n2 n3) (+ n1 n2))
          (define (λ3 i n1 n2 n3) (+ n2 n3))
          (define (aux i n1 n2 n3)
            (if (= i n)
                (list n1 n2 n3)
                (aux (λ0 i n1 n2 n3) 
                     (λ1 i n1 n2 n3)
                     (λ2 i n1 n2 n3)
                     (λ3 i n1 n2 n3)))))
    (aux 0 1 1 1)))

所以这让我们很容易理解为什么我们只使用旧值并且绑定顺序并不重要,因为我们不做任何值绑定。


推荐阅读