对于 clojure 中的这个 SICP 问题,我做错了什么?
What am I doing wrong for this SICP question in clojure?
我正在使用 Clojure 中的 SICP。我坚持练习 1.38。
在 1.37 中,我使用递归和迭代程序来计算有限连分数,然后在 1.38 中,我应该使用该代码来估计欧拉数,其中分数为:
N1/(D1+N2/(D2+N3/(D3...+Nk/Dk)))
其中 e-2 等于 N 始终为 1 且 D 始终为 1, 2, 1, 1, 4, 1, 1, 6, 1, 1, 8, ...
为了计算 e,我想做:
(+ 2 (cont-frac-4 (constantly 1.0) d 10))
其中 d 定义为:
(defn d [i] (if (zero? (rem (+ 2 i) 3)) (* 2 (/ (+ 2 i) 3)) 1))
这适用于我的递归过程:
(defn cont-frac-3 [n d k]
(defn cont-frac-rec [i]
(if (= i k)
0
(/ (n i) (+ (d i) (cont-frac-rec (inc i))))))
(cont-frac-rec 0))
但我的迭代过程没有:(我尝试了 2 种方法并得到相同的错误结果)
;; first iterative try
(defn cont-frac-4 [n d k]
(letfn [(cont-frac-iter [i acc]
(if (zero? i)
acc
(cont-frac-iter (dec i) (/ (n i) (+ (d i) acc)))))]
(cont-frac-iter k 0)))
;; second iterative try
(defn cont-frac-5 [n d k]
(defn frac-iter [i result]
(if (zero? i)
result
(frac-iter (dec i) (/ (n i) (+ (d i) result)))))
(frac-iter (dec k) (/ (n k) (d k))))
我用它作为参考,但它不是用 Clojure 编写的,所以我不确定我遗漏了什么:https://billthelizard.blogspot.com/2010/07/sicp-137-138-and-139-continued.html
感谢您的任何建议!
第一个迭代过程看起来不错,我认为引起问题的是您对 d
的定义,需要重写它以适应迭代过程。这对我有用,并给出与递归过程相同的结果:
(defn cont-frac [n d k]
(letfn [(cont-frac-iter [i acc]
(if (zero? i)
acc
(cont-frac-iter (dec i) (/ (n i) (+ (d i) acc)))))]
(cont-frac-iter k 0)))
(defn d [i]
(if (= (mod i 3) 2)
(* 2 (Math/ceil (/ i 3)))
1))
结果符合预期:
(+ 2 (cont-frac (constantly 1.0) d 10))
=> 2.7182817182817183
我正在使用 Clojure 中的 SICP。我坚持练习 1.38。
在 1.37 中,我使用递归和迭代程序来计算有限连分数,然后在 1.38 中,我应该使用该代码来估计欧拉数,其中分数为:
N1/(D1+N2/(D2+N3/(D3...+Nk/Dk)))
其中 e-2 等于 N 始终为 1 且 D 始终为 1, 2, 1, 1, 4, 1, 1, 6, 1, 1, 8, ...
为了计算 e,我想做:
(+ 2 (cont-frac-4 (constantly 1.0) d 10))
其中 d 定义为:
(defn d [i] (if (zero? (rem (+ 2 i) 3)) (* 2 (/ (+ 2 i) 3)) 1))
这适用于我的递归过程:
(defn cont-frac-3 [n d k]
(defn cont-frac-rec [i]
(if (= i k)
0
(/ (n i) (+ (d i) (cont-frac-rec (inc i))))))
(cont-frac-rec 0))
但我的迭代过程没有:(我尝试了 2 种方法并得到相同的错误结果)
;; first iterative try
(defn cont-frac-4 [n d k]
(letfn [(cont-frac-iter [i acc]
(if (zero? i)
acc
(cont-frac-iter (dec i) (/ (n i) (+ (d i) acc)))))]
(cont-frac-iter k 0)))
;; second iterative try
(defn cont-frac-5 [n d k]
(defn frac-iter [i result]
(if (zero? i)
result
(frac-iter (dec i) (/ (n i) (+ (d i) result)))))
(frac-iter (dec k) (/ (n k) (d k))))
我用它作为参考,但它不是用 Clojure 编写的,所以我不确定我遗漏了什么:https://billthelizard.blogspot.com/2010/07/sicp-137-138-and-139-continued.html
感谢您的任何建议!
第一个迭代过程看起来不错,我认为引起问题的是您对 d
的定义,需要重写它以适应迭代过程。这对我有用,并给出与递归过程相同的结果:
(defn cont-frac [n d k]
(letfn [(cont-frac-iter [i acc]
(if (zero? i)
acc
(cont-frac-iter (dec i) (/ (n i) (+ (d i) acc)))))]
(cont-frac-iter k 0)))
(defn d [i]
(if (= (mod i 3) 2)
(* 2 (Math/ceil (/ i 3)))
1))
结果符合预期:
(+ 2 (cont-frac (constantly 1.0) d 10))
=> 2.7182817182817183