机试算法讲解:第30题 大整数的阶乘

/*
问题:输入一个正整数,输出N的阶乘。本质:高精度乘法:将要乘的小数乘以高精度整数的每一位数并加上来自低位的仅为
输入:正整数N(0<=N<=1000)
输出:可能包括多组数据,对于每一组输入数据,输出N的阶乘
输入:
4
5
15
输出:
24
120
1307674368000

关键:
1 利用printf("%04d",n)表示输出总位数为4位,当不足4位时,补充0
2 重载乘号时,注意ret._digit[ret._size++]必须用返回值自己的_size
*/

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

typedef struct BigInterger{
	int _digit[1000];
	int _size;
	void init();
	void set(int iValue);
	BigInterger operator *(int iValue);
	void outPut();
}BigInterger;

void BigInterger::init()
{
	for(int i = 0 ; i < 1000 ; i++)
	{
		_digit[i] = 0;
	}
	_size = 0;
}

void BigInterger::set(int iValue)
{
	init();
	do{
		int iTemp = iValue % 10000;//除以10000取出余数,即为所要保存的低位
		_digit[_size++] = iTemp;
		iValue /= 10000;//继续向下除以
	}while(0!=iValue);
}

BigInterger BigInterger::operator *(int iValue)
{
	//低位向高位进行乘法操作
	BigInterger ret;
	ret.init();
	int iPass = 0;//设置初始进位为0
	//开始进行乘法操作,循环界限为size
	for(int i = 0 ; i < _size ; i++)
	{
		//int iTempSum = _digit[_size]*iValue + iPass;//开始进行初始化乘法,应该用小整数乘以当前数字并加上来自低位的进位
		int iTempSum = iValue*_digit[i] + iPass;
		iPass = iTempSum / 10000;
		iTempSum %= 10000;//保留后4位
		//ret._digit[_size++] = iTempSum;//这里的_size必须是属于ret的
		ret._digit[ret._size++] = iTempSum;
		//iPass /= 10000;//易错,更新进位,更新进位需要用iTempSum/10000
		
	}
	//如果最高位仍然需要进位,则应进位
	if(0!=iPass)
	{
		//ret._digit[_size++] = iPass;
		ret._digit[ret._size++] = iPass;
	}
	return ret;
}

void BigInterger::outPut()
{
	//从高位向低位依次输出
	bool isFirst = true;//设置第一次进入循环的标记为真
	for(int i = _size - 1 ; i >= 0 ; i--)
	{
		if(!isFirst)
		{
			printf("%04d",_digit[i]);
		}
		else
		{
			printf("%d",_digit[i]);
		}
	}
	printf("\n");
}

int main(int argc,char* argv[])
{
	int iNum;
	BigInterger bigInt;
	while(EOF!=scanf("%d",&iNum))
	{
		bigInt.set(1);
		for(int i = 1 ; i <= iNum ; i++)
		{
			bigInt = bigInt * i;
		}
		bigInt.outPut();
	}
	system("pause");
	getchar();
	return 0 ;
}

你可能感兴趣的:(阶乘,机试算法,大整数阶乘)