Clojure中最大的公约数

时间:2015-09-03 21:55:09

标签: clojure greatest-common-divisor

我已经编写了以下代码来计算两个正数的最大公约数。代码中是否存在一些不是最优或足够的问题,如果是这样的话,那么做GCD的方式是什么呢?

(def gcd (fn [a b] (->> (map (fn [x]
                                 (filter #(zero? (mod x %)) (range 1 (inc x))))
                        [a b])
                        (map set)
                        (apply clojure.set/intersection)
                        (apply max))))

(gcd 1023 858)` => 33

4 个答案:

答案 0 :(得分:7)

使用序列操作进行数值运算(没有换能器)有点重量级,这对recur来说是一个很好的例子:

user> (defn gcd [a b]
        (if (zero? b)
          a
          (recur b (mod a b))))
#'user/gcd
user> (gcd 1023 858)
33

这节省了构建序列然后被丢弃的一些努力/时间。在这种情况下,它会创建两个数字序列的序列,将其转换为两个序列的序列,然后将其粉碎成单个集合,其中最大值为答案。
此外,通常,在定义包含函数的变量时,使用defn(定义函数的缩写),它会自动添加很多有用的工具,比如显示参数类型等。

答案 1 :(得分:0)

这就是我所做的,它有点短,并且它不使用递归:

(defn gcd
  [a b]
  (last
    (filter
      #(and (zero? (mod b %)) (zero? (mod a %)))
      (range 1 (inc (min a b)))
      )
    )
  )

答案 2 :(得分:0)

也许还应该提到“只使用Java”方法:

(defn gcd [a b]
  (.gcd (biginteger a) (biginteger b)))

答案 3 :(得分:-1)

(loop [a (map #(Integer/parseInt %) (clojure.string/split (read-line) #" "))]
    (cond
        (reduce > a) (recur (list (reduce - a) (last a)))
        (reduce < a) (recur (list (- (reduce - a)) (first a)))
        (reduce = a) (println (first a))))