平方根近似 Clojure

Square root approximation Clojure

我遇到错误,不知道如何解决。我必须用近似值计算平方根,它应该在第 20 个元素上停止。

代码:

(defn msqrt [n]
    (aprox  (n 1.0 1)))
(defn aprox [n prox part]
(if (= part 20)
    prox
(+ (/ n (* 2 (aprox n part (+ part 1)))) (/ (aprox n prox (+ part 1))2)))
)
(msqrt 9)

在 Clojure 中,声明函数的顺序很重要。他们不会像 Javascript 那样被吊起来。您可以通过以下任一方法解决此问题:

  1. 将您的 defn aprox 移至 defn msqrt
  2. 以上
  3. declare aprox 添加到文件顶部以使其可用

https://clojuredocs.org/clojure.core/declare

答案可以编译,但是却没有执行它应该执行的操作。 aprox 函数中对 part 的第一个引用应该是 prox:

(defn aprox [n prox part]
  (if (= part 20)
      prox
      (+
        (/ n (* 2 (aprox n prox (inc part))))
        (/ (aprox n prox (inc part)) 2))))

我借此机会改进了布局和简洁性。

有效:

> (msqrt 9)
=> 3.0

但它使相同的递归调用两次。只需要这样做一次:

(defn aprox [n prox part]
  (if (= part 20)
      prox
      (let [deeper-prox (aprox n prox (inc part))]
        (+
          (/ n (* 2 deeper-prox))
          (/ deeper-prox 2)))))

现在大约有二十个递归调用,而不是大约一百万 (2^20)。

我们可以看到它是如何工作的。在递归调用中,

  • part 参数计数到 20,创建调用堆栈二十 深;
  • prox参数使用递归生成和 return 对自身的改进估计;
  • n 参数原样传递。

我们将改进过程重复二十次,折叠到msqrt函数中,也可以得到同样的效果:

(defn msqrt [n]
  (loop [prox 1.0, part 20]
    (if (pos? part)
      (recur (+ (/ n (* 2 prox)) (/ prox 2)) (dec part))
      prox)))