阶乘——高精度求法
2013-01-18 10:38
1211 查看
n! = n * (n-1) * (n-2) * ...* 2 * 1
我们经常说一个算法的时间复杂度是指数级或者阶乘级的非常恐怖的。因为一个很小的数阶乘的结果是很大的一个数。12!=479 001 600, 13!就已经超过了int的表示范围。所以当我们要求一个很大的数的阶乘时,必须使用高精度来表示,否则越界。
阶乘的高精度运算可以模拟一个整数与一个大整数的乘法运算,具体运算过程就和做手算乘法一样,无非是每位相乘,超过10进1
注意:上面说的十进一是十进制运算,每一位表示0~9之间的数,为了提高运算速度,我们还可以以100进制,1000进制,10000进制。。。来进行运算。这就有点类似于基数排序的每个桶的表示范围一样。但是如果不是十进制,需要注意一点的就是,假设100进制,我们得到的第i位数是1,当我们输出结果时,如果直接输出1,显然结果不对,我们应该保证每位都占有两位数。
具体代码如下
#include <stdio.h>
#include <string.h>
const int MAXBIT = 40000;
const int BIT = 10000;
int d[MAXBIT];
int f[MAXBIT];
void BigNumberMultiplyWithN(int *digital, int n, int &bitnum)
{
int i;
//digital[bitnum] = 0;
for (i = 0; i < bitnum; i++)
{
digital[i] *= n;
}
for (i = 0; i < bitnum; i++)
{
if (digital[i] >= BIT && i + 1 < bitnum)
{
digital[i+1] += digital[i] / BIT;
digital[i] %= BIT;
}
}
i = bitnum - 1;
while (digital[i] >= BIT)
{
digital[i+1] += digital[i] / BIT;
digital[i++] %= BIT;
bitnum++;
}
}
void Factorial(int n)
{
int bitnum = 1;
memset(d, 0, sizeof(d));
d[0] = 1;
for (int i = 2; i <= n; i++)
{
BigNumberMultiplyWithN(d, i, bitnum);
}
int i;
for (i = bitnum - 1; i >= 0; i--)
if (d[i])
break;
printf("%d", d[i--]);
for (; i >= 0; i--)
printf("%04d", d[i]);
printf("\n");
}
int main(void)
{
int i, j;
int n;
while (scanf("%d", &n) != EOF)
{
Factorial(n);
}
return 0;
}
我们经常说一个算法的时间复杂度是指数级或者阶乘级的非常恐怖的。因为一个很小的数阶乘的结果是很大的一个数。12!=479 001 600, 13!就已经超过了int的表示范围。所以当我们要求一个很大的数的阶乘时,必须使用高精度来表示,否则越界。
阶乘的高精度运算可以模拟一个整数与一个大整数的乘法运算,具体运算过程就和做手算乘法一样,无非是每位相乘,超过10进1
注意:上面说的十进一是十进制运算,每一位表示0~9之间的数,为了提高运算速度,我们还可以以100进制,1000进制,10000进制。。。来进行运算。这就有点类似于基数排序的每个桶的表示范围一样。但是如果不是十进制,需要注意一点的就是,假设100进制,我们得到的第i位数是1,当我们输出结果时,如果直接输出1,显然结果不对,我们应该保证每位都占有两位数。
具体代码如下
#include <stdio.h>
#include <string.h>
const int MAXBIT = 40000;
const int BIT = 10000;
int d[MAXBIT];
int f[MAXBIT];
void BigNumberMultiplyWithN(int *digital, int n, int &bitnum)
{
int i;
//digital[bitnum] = 0;
for (i = 0; i < bitnum; i++)
{
digital[i] *= n;
}
for (i = 0; i < bitnum; i++)
{
if (digital[i] >= BIT && i + 1 < bitnum)
{
digital[i+1] += digital[i] / BIT;
digital[i] %= BIT;
}
}
i = bitnum - 1;
while (digital[i] >= BIT)
{
digital[i+1] += digital[i] / BIT;
digital[i++] %= BIT;
bitnum++;
}
}
void Factorial(int n)
{
int bitnum = 1;
memset(d, 0, sizeof(d));
d[0] = 1;
for (int i = 2; i <= n; i++)
{
BigNumberMultiplyWithN(d, i, bitnum);
}
int i;
for (i = bitnum - 1; i >= 0; i--)
if (d[i])
break;
printf("%d", d[i--]);
for (; i >= 0; i--)
printf("%04d", d[i]);
printf("\n");
}
int main(void)
{
int i, j;
int n;
while (scanf("%d", &n) != EOF)
{
Factorial(n);
}
return 0;
}
相关文章推荐
- 高精度 求1000以内阶乘 (初学)C++版
- 高精度阶乘运算
- 用高精度方法计算n! ,并显示n!(阶乘)的值。
- 高精度加减法 1000阶乘求法
- 阶乘计算(高精度)
- 高精度-n的阶乘
- 高精度阶乘
- 高精度阶乘、乘方排列组合
- 2018年全国多校算法寒假训练营练习比赛(第三场)- E - 进击吧!阶乘(高精度)
- 高精度阶乘
- POJ 3331 The Idiot of the Year Contest! 高精度阶乘
- HDU 1042 N!(高精度计算阶乘)
- 高精度阶乘
- 算法:高精度阶乘
- 蓝桥杯 高精度阶乘计算
- POJ 3331 The Idiot of the Year Contest! 高精度阶乘
- 大数,高精度计算---大数阶乘
- 九度OJ 1076 N的阶乘 (高精度大数的乘法)
- 计算阶乘 高精度10000! 5000MS内
- hdu1042 N! (高精度\大数阶乘)