高兴什么,你的也不是最快的,我查到一种算法实现了,0.07秒,我这里只有思路。
所以,knocker你的程序也不是最强的!所以不要太k........
阶乘,是求一组数列的乘积,其效率的高低,一、是取决于高精度乘法算法,二、是针对阶乘自身特点算法的优化。
前者,是一种广为习知的技术,虽然不同算法效率可天壤之别,但终究可以通过学习获得,甚至可用鲁迅先生的“拿来主义”;
后者,则有许多的发展空间,这里我将介绍一种由我完全独创的一种方法,欢迎大家讨论,如能起到“抛砖引玉”的效果,那就真正达到了目的。
我在开发“阶乘”类算法时,始终遵循如下原则:
- 参与高精度乘法算法的两数,大小应尽可能地相近;
- 尽可能将乘法转化为乘方;
- 尽可能地优先调用平方;
言归正转,下面以精确计算 1000! 为例,阐述该算法:
记 F1(n) = n*(n-1)*...*1;
F2(n) = n*(n-2)*...*(2 or 1);
Pow2(r) = 2^r;
有 F1(2k+1) = F2(2k+1) * F2(2k)
= Pow2(k) * F2(2k+1) * F1(k),
F1(2k) = Pow2(k) * F2(2k-1) * F1(k),
及 Pow2(u) * Pow2(v) = Pow2(u+v),
∴ 1000! =
F1(1000) = Pow2(500)*F2(999)*
F1(500) = Pow2(750)*F2(999)*F2(499
)*F1(250)
= Pow2(875)*F2(999)*F2(499)*F2(249)*
F1(125) = Pow2(937)*F2(999)*F2(499)*F2(249)*F2(125)*
F1(62)
= Pow2(968)*F2(999)*F2(499)*F2(249)*F2(125)*F2(61)*
F1(31) = Pow2(983)*F2(999)*F2(499)*F2(249)*F2(125)*F2(61)*F2(31)*
F1(15)
= ...
如果你预存了某些小整数阶乘(比如这里的“
F1(15)”),则可提前终止分解,否则直至右边最后一项为“
F1(1)”为止;这样,我们将阶乘转化为2的整数次幂与一些连续奇数的积(或再乘以一个小整数的阶乘);