http://www.csdn.net/expert/Topic/63343.shtm
http://www.csdn.net/expert/Topic/52263.shtm
// jiechen.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <stdlib.h>
// 000000000
// 000000000
#define WEISHU 10000
#define WEISHUBIT 4
#define MW ( WEISHU - 1 )
#define MAXLEN 100000
int num1[MAXLEN];
int num2[MAXLEN];
int num3[MAXLEN];
int resultTemp[MAXLEN];
int resultTempLen;
int mulTemp[MAXLEN];
int mulTempLen;
void showNum( int * num,int len )
{
for(int i=len-1;i>=0;i--)
{
printf("%04d",num[i] );
}
}
int getweishu( int * num,int len )
{
int i;
for(i=len-1;i>=0;i--)
{
if ( i > 0 )
break;
}
if ( i == -1 )
return 1;
int r1 = i * WEISHUBIT;
int n2 = num[i];
if ( n2 == 0 )
return r1;
r1++;
while( n2 >= 10 )
{
r1++;
n2 /= 10;
}
return r1;
}
void showOpera( char * name1,int * num1,int len1 )
{
printf("%s = ",name1);
showNum( num1,len1 );
printf("\n");
}
void add( int * add1,int add1num,int *add2,int add2num,int *add3num )
{
// add1num >= add2num
int i;
//showOpera( "Add1",add1,add1num );
if ( add1num < add2num )
{
for(i=add1num;i<add2num;i++)
{
add1[i] = 0;
}
add1num = add2num;
}
int resultLen = add1num + 1;
int jinwei = 0;
for(i=0;i<add2num;i++)
{
add1[i] += add2[i] + jinwei;
if ( add1[i] > MW )
{
add1[i] -= WEISHU ;
jinwei = 1;
}
else
{
jinwei = 0;
}
}
if ( jinwei == 0 )
{
resultLen = add1num;
}
else
{
for(i=add2num;i<add1num;i++)
{
add1[i] ++;
if ( add1[i] > MW )
{
add1[i] = 0;
}
else
{
jinwei = 0;
break;
}
}
if ( jinwei == 0 )
{
resultLen = add1num;
}
else
{
add1[ add1num ] = 1;
}
}
*add3num = resultLen;
//showOpera("Add2",add2,add2num);
//showOpera("Add1 + Add2",add1,resultLen );
}
void mult( int * mul1,int mul1num,int *mul2,int mul2num,int *mul3,int *mul3num )
{
int i,j;
int result;
int jinwei = 0;
int kk;
resultTempLen = mul2num;
for(i=0;i<mul2num+mul1num+1;i++)
{
resultTemp[i] = 0;
}
for(i=0;i<mul2num;i++)
{
jinwei = 0;
for(j=0;j<mul1num;j++)
{
result = mul2[i] * mul1[j] + jinwei;
if ( result > MW )
{
mulTemp[j] = result % WEISHU;
jinwei = result / WEISHU;
}
else
{
mulTemp[j] = result;
jinwei = 0;
}
}
if ( jinwei > 0 )
{
mulTempLen = mul1num+1;
mulTemp[mul1num] = jinwei;
}
else
{
mulTempLen = mul1num;
}
//showOpera("Mul1",mul1,mul1num);
//showOpera("Nul2",mul2+i,1);
//showOpera("Mul2 * Mul1",mulTemp,mulTempLen );
kk = resultTempLen;
add( resultTemp+i,kk-i,mulTemp,mulTempLen,&kk );
resultTempLen = kk + i;
}
*mul3num = resultTempLen;
for(i=0;i<resultTempLen;i++)
{
mul3[i] = resultTemp[i];
}
}
// 10! = 3628800
int ten( int num )
{
int re = 1;
for(int i=2;i<=num;i++)
re *= i;
return re;
}
void setNum( int num,int * n,int * len )
{
int i = 0;
while(num>0)
{
n[i] = num % WEISHU;
num /= WEISHU;
i++;
}
*len = i;
}
void cal(int num)
{
int i,j;
if ( num <= 10 )
{
printf("%d! = %d\n",num, ten(num));
return;
}
int len1,len2,len3;
setNum( 3628800,num1,&len1);
for(i=11;i<=num;i++)
{
setNum( i,num2,&len2 );
mult( num1,len1,num2,len2,num3,&len3 );
for(j=0;j<len3;j++)
{
num1[j] = num3[j];
}
len1 = len3;
}
printf("%d! = ",num);
showNum( num3,len3 );
printf("\nWeiShu = %d\n",getweishu(num3,len3));
}
void main(int argc, char* argv[])
{
if ( argc != 2 )
{
printf("Usage : Jiechen number\n");
return;
}
int num = atoi( argv[1] );
if ( num <= 0 )
{
printf("Arg %s is invalid!\n",argv[1]);
return;
}
cal(num);
}
*************
程序包含两个文件,
一个是执行窗体文件(包含组件:1个SpinEdit1,一个Edit,一个Button1,三个标签Label1,Label2,Label3),
另一个是类定义文件(Unit_factorial_class.pas),具体如下:
窗体定义文件:
unit Unit_Main;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, Spin;
type
TForm1 = class(TForm)
Button1: TButton;
SpinEdit1: TSpinEdit;
Edit1: TEdit;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
uses
//使用类单元
Unit_factorial_class;
var
MyFactorial:TLQM_factorial_class;
procedure TForm1.Button1Click(Sender: TObject);
var
time1,time2:TTime;
begin
//创建对象
MyFactorial:=TLQM_factorial_class.Create;
label3.Caption:='Number: '+IntToStr(SpinEdit1.Value);
time1:=time;
//计算
Edit1.text:=string(MyFactorial.CaculateFactorial(SpinEdit1.Value));
time2:=time;
Label1.Caption:='Length: '+IntToStr(length(Edit1.text));
Label2.Caption:='Time: '+TimeToStr(time2-time1);
//销毁对象
MyFactorial.Free;
end;
end.
类定义文件(Unit_factorial_class.pas)内容为:
//-----------------------------------------------------------------------------
unit Unit_factorial_class;
interface
type
//数据结构-----------------------------------------------------
//-------------------------------------------------------------
//用于存储结果的每一个位(十进制位)的数据结构
TLQM_Factorial_Record_p=^TLQM_factorial_record;
TLQM_Factorial_Record=record
//只需用于保存0-9的数字,
//理论上的最大计算范围为[High(Integer)/10]的取值范围
//实际鉴于系统资源而定
Value:integer;
//指向高位的指针
HighPointer:TLQM_Factorial_Record_p;
end;
//类结构-------------------------------------------------------
//-------------------------------------------------------------
//用于实际计算的阶乘的类
TLQM_factorial_class=class(TObject)
//头节点指针
F_Head:TLQM_factorial_record_p;
private
//将指定值与链表中的值相乘(未进行值的标准处理)
//即:结果链表中的每个位都有可能是多位数
procedure Linklist_MultiplyValue_BlindMultiply(Value:integer);
//将最高位的值扩展到新加的高位字节(递归)
procedure Linklist_MultiplyValue_ExtendTopValue(
Top_p:TLQM_factorial_record_p);
//将链表中的值进行标准处理
//即:结果链表中的每个位只有一个个位数[0-9]
procedure Linklist_MultiplyValue_Fluency;
//将指定值与链表中的值相乘,生成标准的可输出值
//即:结果链表中的每个位只有一个个位数[0-9]
procedure Linklist_MultiplyValue(Value:integer);
//输出链表(注:由低位至高位,最高位的0不算)
function Linklist_OutputString:WideString;
public
//构造函数
constructor Create;
//计算阶乘的函数(当输入错误数[如:-1阶乘]时,返回字符串'-1')
function CaculateFactorial(UserValue:integer):WideString;
//析构函数
destructor Destroy;override;
end;
implementation
uses
Sysutils;
//构造函数
constructor TLQM_factorial_class.Create;
var
s:TLQM_factorial_record_p;
begin
//新建头节点-------------------------------------------------
new(s); s^.Value:=0; s^.HighPointer:=nil; F_Head:=s;
//创建并设置初始节点值为1------------------------------------
new(s); s^.Value:=1; s^.HighPointer:=nil; F_Head^.HighPointer:=s;
end;
//将指定值与链表中的值相乘(未进行值的标准处理)
//即:结果链表中的每个位都有可能是多位数
procedure TLQM_factorial_class.Linklist_MultiplyValue_BlindMultiply(Value:integer);
var
p:TLQM_factorial_record_p;
begin
p:=F_Head^.HighPointer;
while p<>nil do
begin
p^.Value:=p^.Value*Value;
p:=p^.HighPointer;
end;
end;
//将最高位的值扩展到新加的高位字节(递归)
procedure TLQM_factorial_class.Linklist_MultiplyValue_ExtendTopValue(
Top_p:TLQM_factorial_record_p);
var
s:TLQM_factorial_record_p;
begin
//若已经无高位,则退出
if (Top_p^.Value div 10)=0 then Exit;
//创建更高位-------------------------------------------------
new(s); Top_p^.HighPointer:=s; s^.HighPointer:=nil;
//将高位值存入s
s^.Value:=Top_p^.Value div 10;
//保留个位值
Top_p^.Value:=Top_p^.Value mod 10;
//继续扩展
Linklist_MultiplyValue_ExtendTopValue(s);
end;
//将链表中的值进行标准处理
//即:结果链表中的每个位只有一个个位数[0-9]
procedure TLQM_factorial_class.Linklist_MultiplyValue_Fluency;
var
s,p:TLQM_factorial_record_p;
begin
//一直循环到最高位(但最高位不在内)
p:=F_Head^.HighPointer;
//若不是最高位,则将本位的个位值保留,高位值进到高位
while p^.HighPointer<>nil do
begin
//s指向高一位
s:=p^.HighPointer;
s^.Value:=s^.Value+p^.Value div 10;
p^.Value:=p^.Value mod 10;
p:=p^.HighPointer;
end;
//将最高位的值分解到"另外扩展的"更高的位
//(注:当前指针已经指向最高位)
Linklist_MultiplyValue_ExtendTopValue(p);
end;
//将指定值与链表中的值相乘
procedure TLQM_factorial_class.Linklist_MultiplyValue(Value:integer);
begin
//将指定值与链表中的值相乘(未进行值的标准处理)
//即:结果链表中的每个位都有可能是多位数
Linklist_MultiplyValue_BlindMultiply(Value);
//将链表中的值进行标准处理
//即:结果链表中的每个位只有一个个位数[0-9]
Linklist_MultiplyValue_Fluency;
end;
//输出链表(注:由低位至高位)
function TLQM_factorial_class.Linklist_OutputString:WideString;
var
p:TLQM_factorial_record_p;
begin
Result:='';
p:=F_Head^.HighPointer;
while p<>nil do
begin
Result:=Result+IntToStr(p^.Value);
p:=p^.HighPointer;
end;
end;
//计算阶乘的函数
function TLQM_factorial_class.CaculateFactorial(UserValue:integer):WideString;
var
i:integer;
begin
//若为小于0的数的阶乘,返回字符串'-1'
if UserValue<0 then begin Result:='-1'; Exit; end;
//若为0或1的阶乘,返回字符串'1'
if (UserValue in [0,1]) then begin Result:='1'; Exit; end;
//计算函数的主体部分
for i:=UserValue downto 2 do
begin
Linklist_MultiplyValue(i);
end;
//输出链表(注:由低位至高位)
Result:=Linklist_OutputString;
end;
//析构函数
destructor TLQM_factorial_class.Destroy;
var
s,p:TLQM_factorial_record_p;
begin
//释放空间
p:=F_Head^.HighPointer;
while p<>nil do
begin
s:=p; p:=p^.HighPointer; Dispose(s);
end;
Dispose(F_Head);
inherited Destroy;
end;
end.