大数阶乘

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

void Factorial(int n);

int main()
{
	int n;
	clock_t start,finish;
	double duration;

	while (printf("\nInput a number:  "),scanf("%d",&n)!=EOF)
	{
		start=clock();
		Factorial(n);
		finish=clock();
		duration=(double)(finish-start)/CLOCKS_PER_SEC;
		printf("Time consumed is :  %.2lf\n",duration);
	}
	return 0;
}

void Factorial(int n)
{
	int a[100000],tail=0;//tail是最高位的下标
	int i,j,iCarry;  //iCarry是进位
	
	a[0]=1;
	for (i=2;i<=n;i++)
	{
		iCarry=0;  //每次*i前将进位置0
		for (j=0;j<=tail;j++)
		{
			if (iCarry==0&&a[j]==0) //如果当前位是0并且无进位
			{
				continue;
			}

			a[j]=a[j]*i+iCarry;  //当前数位*i+进位
			iCarry=a[j]/10000;   //求新的进位
			a[j]%=10000;         //更新当前数位
		}

		if (iCarry)  //如果超过当前解的长度,将进位添加到解中
		{
			a[++tail]=iCarry;
		}	
	}

	for (i=tail;i>=0;i--) //输出
	{
		printf("%d",a[i]);
	}
	printf("\n");
}


今天一个偶然的机会,发现这个程序有问题!

不信可以输入8试试,结果为4320,这与正确答案40320相比显然错误!

7!=5040;  此时a[0]=5040;  a[0]*8=40320;   a[0]%=10000后 a[0]=320!!!发现错误了吧!

怎样修改呢?可以使用printf输出固定宽度的数字,不足左补零的方法!

附代码:

#include <stdio.h>

void calFac(int n);

int main()
{
	int n;

	while (scanf("%d",&n)!=EOF)
	{
		calFac(n);
	}

	return 0;
}

void calFac(int n)
{
	int iRes[40000],iIndex=0;
	int iCarry,i,j;

	iRes[0]=1;
	for (i=2;i<=n;i++)
	{
		iCarry=0;
		for (j=0;j<=iIndex;j++)
		{
			if (iRes[j]==0&&iCarry==0)
			{
				continue;
			}
			iRes[j]=iRes[j]*i+iCarry;
			iCarry=iRes[j]/10000;
			iRes[j]%=10000;
		}
		if (iCarry!=0)
		{
			iRes[++iIndex]=iCarry;
		}
	}

	printf("%d",iRes[iIndex]);
	for (i=iIndex-1;i>=0;i--)
	{
		printf("%04d",iRes[i]);
	}
	printf("\n");
}

有一个一个稳当的算法,但比较慢!(HDU上390MS,上面是1700MS)

#include <stdio.h>

void calFac(int n);

int main()
{
	int n;

	while (scanf("%d",&n)!=EOF)
	{
		calFac(n);
	}

	return 0;
}

void calFac(int n)
{
	int iRes[40000],iIndex=0;
	int iCarry,i,j;

	iRes[0]=1;
	for (i=2;i<=n;i++)
	{
		iCarry=0;
		for (j=0;j<=iIndex;j++)
		{
			if (iRes[j]==0&&iCarry==0)
			{
				continue;
			}
			iRes[j]=iRes[j]*i+iCarry;
			iCarry=iRes[j]/10;
			iRes[j]%=10;
		}
		while (iCarry!=0)
		{
			iRes[++iIndex]=iCarry%10;
			iCarry/=10;

		}
	}

	for (i=iIndex;i>=0;i--)
	{
		printf("%d",iRes[i]);
	}
	printf("\n");
}


你可能感兴趣的:(大数阶乘)