有关阶乘的算法,不外乎两个方面:一是高精度计算;二是与数论相关。
一. 高精度计算阶乘
这实际上是最没有技术含量的问题,但是又会经常用到,所以还是得编写,优化它的计算。
首先看小于等于12的阶乘计算(计算结果不会超出32位范围):
int factorial(int n)
{
if (n == 1 || n == 0) return 1;
return factorial(n-1)*n;
}
这个递归程序简单明了,非常直观,然而一旦n > 12,则超过32位int型的范围出现错误结果,所以上面这个递归程序仅适合n <= 12的阶乘计算,为了计算较大n的阶乘,需要将高精度乘法算法纳入到阶乘计算中来,高精度乘法过程可以如下简单的描述:(其中A * B = C,A[0], B[0], C[0]分别存储长度)
for (i = 1; i <= A[0]; i++)
for (j = 1; j <= B[0]; j++) {
C[i+j-1] += A[i]*B[j]; // 当前i+j-1位对应项 + A[i] * B[j]
C[i+j] += C[i+j-1]/10; // 它的后一位 + 它的商(进位)
C[i+j-1] %= 10; // 它再取余即可
}
C[0] = A[0] + B[0];
while (C[0] > 1 && C[C[0]] == 0) C[0]--; // 去头0,获得实际C的长度
有了这个高精度乘法之后,计算阶乘就可以简单的迭代进行:
for (i = 2; i <= n; i++) {
将i转换成字符数组;
执行高精度乘法:将上一次结果乘上i
}

本文探讨了阶乘计算的两个主要方面:高精度计算和数论相关问题。针对高精度计算,文章给出了递归和迭代的解决方案,并详细解释了高精度乘法算法。在数论部分,文章列举了几种与阶乘相关的数论问题,如求阶乘末尾第一个非0数字、阶乘末尾0的数量以及阶乘的位数等,并提供了相应的求解思路和方法。

798

被折叠的 条评论
为什么被折叠?



