大数阶乘算法
一:精度要求较低的阶乘算法如果只是要求算法的速度,而对精度要求比较低的话可以直接使用,斯特林公式计算n! 斯特林公式如下:
或
这里PI为圆周率,而最后一顼为雅格布·伯努力数是无穷的级数,这里我们取前5项即可得到接近16位有效数字的近似值,而精度的提高可由雅格布·伯努力数取的项数增加而得到。 另也可对斯特林公式进行修行,下面即为蔡永裕先生的《谈Stirling公式的改良》一文中得出的斯特林公式的修正版:
该公式可以得到较高的精度,较计算也较方便。 二:高精度阶乘算法算法1:硬乘最容易想到的自然是硬乘。模拟人工计算乘法的方法,一位位的乘。以AB*C为例,其中A,B,C各占一个基数位,以N进制为例。 第一步:
第二步:
第三步:
由此可估计该算法的复杂度约为:T(n) =O(n!),是一个NP难问题。?
算法2:分治法 ?
1? 假如已经求得n!(共有m个单元),求(n+16)! ?
第二步:
第三步:
第四步:
假定求余运算和除法运算和乘法的复杂度相同,则可知其符合分治法所需时间的计算公式,故可得:?? T(n) = log(n^2) 因数学水平及时间有限不能给出算法1和算法2的精确? 第二种算法表明,在计算阶乘时,通常的方法(先计算出n的阶乘,再用一位数乘以多位数的方法计算(n+1)的阶乘,再计算n+2的阶乘)不是最优的,更优化的算法是,计算出相邻的几个数的积(称之为部分积),用部分积乘以部分积的这种多位数乘以? 2? 两个数相乘 设X和Y都是n(n是偶数)位的L进制的整数(当X,Y位数不等时,可在较小的数的左边补零来使其位数和较大的数相等。如X=123,Y=4325,则令X=0123)。在第一种算法中,两个大数相乘采用的是硬乘。效率较低,如果将每两个一位数的乘法或加法看作一步运算的话,那么这种方法要作O(n^2)步运算才能求出乘积XY。 这里我们用二分法来计算大数乘法。将n位的L进制的X和Y都分为2段,每段的长为n/2(如n为奇数可在左边加零),如下图如示:
由此,X=A*L^(n/2)+B? 所以 X*Y = (A*L^(n/2)+B)(C*L^(n/2)+D)? 而AD+BC = (A-B)(D-C)+AC +BD 所以 X*Y= AC*L^n +((A-B)(D-C)+AC +BD)*L^(n/2)+BD 此时,此式仅需做3次n/2位整数的乘法(AC,BD和(A-B)(D-C)),6次加、减法和2次移位。由此可得: T(n) = O(1)? T(n) = 3T(n/2)+O(n)? 根据分治法效率计算公式可得:T(n)= O(n^log3) =O(n^1.59) 同理,若将n三等分,则 (Axx+Bx+C)*(Dxx+Ex+F)=ADxx+(AE+BD)xxx+(AF+BE+CD)xx+(BF+CE)x+CF =ADxxxx+[(A-B)(E-D)+AD+BE]xxx+[BE+(A-C)(F-D)+CF+AD]xx+[(B-C)(F-E)+CF+BE]+CF 可知此式仅需做6次n/3位整数的乘法, 根据分治法效率计算公式可得:T(n)= O(n^log6/3) =O(n^2) 取自:http://blog.sina.com.cn/s/blog_40a3dcc1010008nf.html 相关实现:#include<iostream>
#define MAX 1000
using namespace std;
int main(void)
{
int n;
while(scanf("%d",&n)==1&&n>=0)
{
int i,j;
int a[MAX]; //存数运算结果
int p,h; //p存储当前结果的位数,h为进位
a[1]=1;
p=1;
for(i=2;i<=n;i++) //循环与2,3,4.....n相乘
{
for(j=1,h=0;j<=p;j++) //让a[]的每位与i相乘
{
a[j]=a[j]*i+h;
h=a[j]/10;
a[j]=a[j]%10;
}
while(h>0) //如果h不为0
{
a[j]=h%10;
h=h/10;
j++;
}
p=j-1; //将当前的位数赋给p
}
for(i=p;i>=2;i--)
{
printf("%d",a[i]);
}
printf("%dn",a[i]);
}
return 0;
}
取自:http://www.cnblogs.com/dolphin0520/archive/2011/07/16/2108006.html 代码解读:首先,定义两个整型的数组: 取自:http://blog.csdn.net/jaylongli/article/details/4865035 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |

