Clojure牛顿法求n次根:while循环失效问题求助
牛顿法求n次根的问题修复
嘿,我帮你梳理下代码里的问题,顺便给你修正后的实现~
首先你的代码里有几个明显的语法和逻辑问题:
- 函数定义错误:
count_root的定义格式完全不符合Clojure规范,正确的defn格式应该是(defn 函数名 [参数列表] 函数体),你写的(defn count_root nth guess [nth guess])会直接报错。 - 全局变量滥用:在函数内部用
def定义result、last_result这些变量是错误的,def会创建全局绑定,应该用let创建局部变量,或者用Clojure更偏好的递归方式(loop/recur)处理循环逻辑。 - 牛顿迭代公式不完整:你代码里的
(/ guess ...)没写完,而且正确的n次根迭代公式应该是:x_{k+1} = (1/n) * ((n-1)*x_k + target/(x_k^{n-1})),另外你参数命名有点混淆,guess应该是要开根的目标数,初始猜测值需要单独传参。 - 缺少内置函数:Clojure没有
power和absolute,得用Java的Math/pow和Math/abs替代。
修正后的实现(用loop/recur,更符合Clojure风格)
(defn nth-root [n target initial-guess] (cond (<= target 0) "Root doesn't exist for non-positive numbers" (<= n 0) "n must be a positive integer" :else (loop [guess initial-guess last-guess 0.0] (if (<= (Math/abs (- guess last-guess)) 0.01) guess (recur (/ (+ (* (dec n) guess) (/ target (Math/pow guess (dec n)))) n) guess))))) ;; 测试示例:求8的3次根,初始猜测为2.5 (nth-root 3 8 2.5) ; 会返回接近2.0的结果
如果你坚持用while循环的版本(用let创建局部变量)
(defn nth-root-while [n target initial-guess] (cond (<= target 0) "Root doesn't exist for non-positive numbers" (<= n 0) "n must be a positive integer" :else (let [tolerance 0.01] (loop [guess initial-guess last-guess 0.0] (if (> (Math/abs (- guess last-guess)) tolerance) (recur (/ (+ (* (dec n) guess) (/ target (Math/pow guess (dec n)))) n) guess) guess)))))
补充说明
- 我把参数名改得更清晰了:
n是根的次数,target是要开根的数,initial-guess是初始猜测值,避免混淆。 - 增加了参数合法性检查,比如n必须是正整数,target必须是正数(偶数根的情况下target不能为负)。
- 用
loop/recur替代了while循环,这是Clojure里更惯用的循环方式,不会有全局变量的问题。
内容的提问来源于stack exchange,提问作者Boba_Fett
相关产品推荐
相关产品推荐

