2

我正在学习 Clojure,我刚刚开始使用Project Euler,但遇到了一个我无法弄清楚的问题。这是我的代码:

(defn largest_prime_factor
  [x]
  (if (prime? x) x)
  (loop [running x divider 2]
    (if (= 0 (mod running divider))
      (let [d (/ running divider)]
        (if (prime? d)
          d
          (recur d 2)))
      (recur x (inc divider)))))

(largest_prime_factor 12)  ;works
(largest_prime_factor 49)  ;works
(largest_prime_factor 147) ;Endless loop!

我意识到这可能不是找到最大素数的最有效方法,但我想弄清楚它为什么会陷入循环。显然我以错误的方式使用循环递归但我做错了什么?

4

2 回答 2

3
(if (prime? x) x)

我想你的意思是

(if (prime? x) x
  (loop [...
于 2013-03-20T23:40:16.610 回答
3

几件事

(defn largest_prime_factor
  [x]
  (if (prime? x) x)                 ; #1
  (loop [running x divider 2]
    (if (= 0 (mod running divider))
      (let [d (/ running divider)]
        (if (prime? d)
          d
          (recur d 2)))
      (recur x (inc divider)))))    ; #2
  1. 额外的右括号使它成为一个独立的ifelse子句。这与无限循环无关,但会为素数输入给出错误的答案 (1)(除非您改为从 1 开始除法器,在这种情况下您可以省略此初始测试)。

  2. 这条线应该用running而不是重复出现x,否则你没有分解除数并且prime?测试将永远是错误的。这就是为什么你会陷入无限循环。

于 2013-03-21T01:08:24.127 回答