我已经编写了以下代码来计算两个正数的最大公约数。代码中是否存在一些不是最优或足够的问题,如果是这样的话,那么做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
答案 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))))