我在Clojure中制作了简单的阶乘程序。
(defn fac [x y]
(if (= x 1) y (recur (- x 1) (* y x)))
)
(def fact [n] (fac n 1))
如何更快地完成?如果能以更快的方式完成。
答案 0 :(得分:2)
您可以在此处找到许多快速因子算法:http://www.luschny.de/math/factorial/FastFactorialFunctions.htm
如上所述,Clojure不是最好的语言。考虑使用C,C ++,ForTran。
请注意您使用的数据结构,因为因子的增长非常快。
答案 1 :(得分:2)
在您自己的fact
函数(或任何其他函数)的帮助下,我们可以定义这个非常快的版本:
(def fact* (mapv fact (cons 1 (range 1 21))))
这将为常量时间范围为1到20的参数提供正确的结果。超出该范围,您的版本也没有给出正确的结果(即整数溢出(fact 21)
)。
编辑:这是一个改进的实现,不需要另一个fact
实现,不会溢出,并且在定义期间应该快得多,因为它不会计算其查找中的每个条目从头开始:
(def fact (persistent! (reduce (fn [v n] (conj! v (*' (v n) (inc n))))
(transient [1])
(range 1000))))
编辑2 :对于不同的快速解决方案,即无需构建查找表,最好使用已经高度优化的库。 Google的通用实用程序库Guava包含一个因子实现。
通过添加此Leiningen依赖项将其添加到您的项目中:[com.google.guava/guava "15.0"]
。然后,您需要(import com.google.common.math.BigIntegerMath)
,然后可以使用(BigIntegerMath/factorial n)
调用它。
答案 2 :(得分:2)
这是我的最爱:
(defn fact [n] (reduce *' (range 1 (inc n))))
'告诉Clojure透明地使用BigInteger以避免溢出。