关于最小公倍数

求最大公约数的算法众所周知,使用辗转取余法(辗转相除法)

但怎么求n个数的最小公倍数呢,

常规解法有两种,

一种是质因数分解,设每个出现过的质因数 p[i]所出现的最大次数为a[i],则把所有Math.pow(p[i], a[i[)相乘即可,不过这种方法局限于

正整数

还有一种是假设两数分别为a, b,求出最大公约数gcd[0], a[1] = a/gcd[0], b[1] = b/gcd[0] ,再把a[i], b[i]这样处理直到a[i], b[i]互质为止,这是把所有的gcd[k] (k

(defn lcm [& nums]
  (let [index-of (fn [v l] 
    (loop [i 0] 
      ; get the index of value v in sequence l. assume v is in l
      (if (= (nth l i) v)
        i 
        (recur (inc i)))) ) 
    lcm-help (fn [now-nums origin-nums]
                (if (apply = now-nums)
                  (first now-nums)
                  (let [min-value (apply min now-nums)
                        min-value-index (index-of min-value now-nums)
                        origin-val (nth origin-nums min-value-index)
                        new-val (+ min-value origin-val)
                        now-nums-vector (vec now-nums)
                        new-now-nums-vector (assoc now-nums-vector 
                                              min-value-index new-val)
                        new-now-nums (seq new-now-nums-vector)]
                    (recur new-now-nums origin-nums))))]
      (lcm-help nums nums)))

(println (lcm 7 5/7 2 3/5))
(println (lcm 3/4 1/6))

输出结果为210, 3/2