1

テスト機能は以下のとおりです。

(defun fab (n) 
    (let ((res '(1 1)))
        (loop for i from 2 to n do
            (nconc res (list (+ (nth (- i 2) res) (nth (- i 1) res)))))
        res))

$ ecl

... EECL(Embeddable Common-Lisp)12.7.1(git:UNKNOWN)

..。

>(fab 10)
(1 1 2 3 5 8 13 21 34 55 89)
>(fab 20)
(1 1 2 3 5 8 13 21 34 55 89 2 3 5 8 13 21 34 55 89 144 91 5 8 13 21 34 55 89 144

次に、ECLを再起動します

>(fab 20)
(1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946)

(fac 10)の後に「res」が解放されていないようです。

心から!

4

2 に答える 2

4

フォームでは(list 1 1)なく使用する必要があります。Common Lispでは、リテラルオブジェクトを変更した場合の影響は定義されていません。'(1 1)let

(defun fib (n)
  (let ((res (list 1 1))) ; (list 1 1) instead of '(1 1)
    (loop for i from 2 to n
          do (nconc res (list (+ (nth (- i 2) res) (nth (- i 1) res)))))
    res))
于 2012-09-21T01:21:24.470 に答える
1

'(1 1)などの定数は、コンパイラー/インタープリターによって1回だけ割り当てられます。コードはこのリストでNCONCを使用し、変更すると、後続の呼び出しでは定数リスト'(1 1)は表示されなくなり、変更されたリストが表示されます。Common Lispでは、定数式を破壊的に変更したときに何が起こるかは特定されておらず、一部の実装では、そのような驚きを避けるために変更からそれらを保護しています。新しい定数が必要な場合は、人々が言っ​​たように実行して(リスト1 1)を使用するか、NCONCの使用を完全に避けてください。

于 2012-09-25T14:19:43.217 に答える