数组下标由低到高依次存放个,十,百.....然后从最后找出第一个非0元输出即可
逢10进1,每次i与数组中每一项进项相乘,这是初步算法
代码如下。
#include<stdio.h>
#include<string.h>
#define MAX 50000
int main(void)
{
int num[MAX], n, temp;
while (scanf("%d", &n) != EOF) {
memset(num, 0, sizeof(num));
num[0] = 1;
for (int i = 1; i <= n; i++) {
for (int j = 0, temp = 0; j < MAX; j++) {
num[j] = num[j] * i + temp;
temp = num[j] / 10;
num[j] = num[j] % 10;
}
}
for (int i = MAX - 1; i >= 0; i--) {
if (num[i]) {
temp = i;
break;
}
}
for (int i = temp; i >= 0; i--) {
printf("%d", num[i]);
}
putchar('\n');
}
}
是因为代码效率过低,没必要每次乘以char ch[40000],只需要乘以当前数组中应有的位数即可
将每个阶乘应有的位提前用一个数组保存,读取的时候没必要从最后开始,从阶乘应有的位数开始即可。
任意一个正整数a的位数 等于(int)log10(a) + 1
优化后的代码如下
#include<stdio.h>
#include<string.h>
#include<math.h>
#define MAX 40000
int num[MAX];
double len[10000];
int main(void)
{
int n, temp;
len[0] = 0;
for (int i = 1; i <= 10000; i++)
len[i] = len[i-1] + log10((double)i);
while (scanf("%d", &n) != EOF) {
memset(num, 0, sizeof(num));
num[0] = 1;
for (int i = 1; i <= n; i++) {
for (int j = 0, temp = 0; j <= (int)len[i]+1; j++) {
num[j] = num[j]*i + temp;
temp = num[j] / 10;
num[j] = num[j] % 10;
}
}
for (int i = (int)len[n] + 1; i >= 0; i--) {
if (num[i]) {
temp = i;
break;
}
}
for (int j = temp; j >= 0; j--) {
printf("%d", num[j]);
}
putchar('\n');
}
}
发现某大神的1000万的阶乘只要0.02秒,0.02秒,0.02秒,什么概念!
各位对大数阶乘感兴趣的可以去看看他的
http://www.cnblogs.com/carekee/articles/2569593.html