高精度阶乘和 pascal 求10000以内的阶乘,时间要求要高!
发布网友
发布时间:2024-09-26 19:54
我来回答
共2个回答
热心网友
时间:2024-11-14 06:32
首先定义一个阶乘的类。代码如下:
unit Unit_Factorial_class;
interface
type
//数据结构
//用于存储结果的每一个位(十进制位)的数据结构
pTLQM_Factorial_Record=^TLQM_Factorial_Record;
TLQM_Factorial_Record=record
//只需用于保存0-9的数字
//理论上的最大计算范围为[High(Integer)/10]的取值范围
//实际鉴于系统资源而定
Value:Integer;
//指向高位的指针
HighPointer:pTLQM_Factorial_Record;
end;
//类结构
TLQM_Factorial_Class=Class(TObject)
//头节点指针
F_Head:pTLQM_Factorial_Record;
private
//将指定值与链表中的值相乘(未进行值的标准处理)
//即:结果链表中的每个位都有可能是多位数
procere LinkList_MultiplyValue_BlindMultiply(Value:Integer);
//将最高位的值扩展到新加的高位字节(递归)
procere LinkList_MultiplyValue_ExtendTopValue(p_Top:pTLQM_Factorial_Record);
//将链表中的值进行标准处理
//即:结果链表中的每个位只有一个个位数[0-9]
procere LinkList_MultiplyValue_Fluency;
//将指定值与链表中的值相乘,生成标准的可输出值
//即:结果链表中的每个位只有一个个位数[0-9]
procere LinkList_MultiplyValue(Value:Integer);
//输出链表(注:由低位至高位,最高位的0不算)
Function LinkList_OutputString:WideString;
public
//构造函数
constructor Create;
//计算阶乘的函数(当输入错误数[如:-1阶乘]时,返回字符串'-1')
Function CaculateFactorial(UserValue:Integer):WideString;
//把字符串的高位与低位反转
Function ExchangePos(Astr:WideString):WideString;
//正序输出
Function FactorialOutput(UserValue:Integer):WideString;
//析构函数
destructor Destroy;Override;
End;
implementation
uses
SysUtils;
{ TLQM_Factorial_Class }
//计算阶乘的函数
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;
//构造函数
constructor TLQM_Factorial_Class.Create;
var
s:pTLQM_Factorial_Record;
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;
//析构函数
destructor TLQM_Factorial_Class.Destroy;
var
s,p:pTLQM_Factorial_Record;
begin//
//释放空间
p:=F_Head^.HighPointer;
while p<>nil do
begin
s:=p;
p:=p^.HighPointer;
Dispose(s);
end;
Dispose(F_Head);
inherited Destroy;
end;
//把字符串的高位与低位反转
function TLQM_Factorial_Class.ExchangePos(Astr: WideString): WideString;
var
i:Integer;
begin//
Result:='';
for I := Length(Astr) downto 1 do
begin
Result:=Result+AStr[i];
end;
end;
//正序输出
function TLQM_Factorial_Class.FactorialOutput(UserValue: Integer): WideString;
begin
Result:=ExchangePos(String(CaculateFactorial(UserValue)));
end;
//将指定值与链表中的值相乘,生成标准的可输出值
//即:结果链表中的每个位只有一个个位数[0-9]
procere TLQM_Factorial_Class.LinkList_MultiplyValue(Value: Integer);
begin//
//将指定值与链表中的值相乘(未进行值的标准处理)
//即:结果链表中的每个位都有可能是多位数
LinkList_MultiplyValue_BlindMultiply(Value);
//将链表中的值进行标准处理
//即:结果链表中的每个位只有一个个位数[0-9]
LinkList_MultiplyValue_Fluency;
end;
//将指定值与链表中的值相乘(未进行值的标准处理)
//即:结果链表中的每个位都有可能是多位数
procere TLQM_Factorial_Class.LinkList_MultiplyValue_BlindMultiply(
Value: Integer);
var
p:pTLQM_Factorial_Record;
begin//
p:=F_Head^.HighPointer;
while p<>nil do
begin
p^.Value:=p^.Value*Value;
p:=p^.HighPointer;
end;
end;
//将最高位的值扩展到新加的高位字节(递归)
procere TLQM_Factorial_Class.LinkList_MultiplyValue_ExtendTopValue(
p_Top: pTLQM_Factorial_Record);
var
s:pTLQM_Factorial_Record;
begin//
//若已经无高位,则退出
if(p_Top^.Value div 10)=0 then Exit;
//创建更高位
new(s);
p_Top^.HighPointer:=s;
s^.HighPointer:=nil;
//将高位值存入s
s^.Value:=p_Top^.Value div 10;
//保留个位值
p_Top^.Value:=p_Top^.Value mod 10;
//继续扩展
LinkList_MultiplyValue_ExtendTopValue(s);
end;
//将链表中的值进行标准处理
//即:结果链表中的每个位只有一个个位数[0-9]
procere TLQM_Factorial_Class.LinkList_MultiplyValue_Fluency;
var
s,p:pTLQM_Factorial_Record;
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;
//输出链表(注:由低位至高位,最高位的0不算)
function TLQM_Factorial_Class.LinkList_OutputString: WideString;
var
p:pTLQM_Factorial_Record;
begin//
Result:='';
p:=F_Head^.HighPointer;
while p<>nil do
begin
Result:=Result+IntToStr(p^.Value);
p:=p^.HighPointer;
end;
end;
end.
下面是调用窗体:
unit Unit3;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls, Spin;
type
TForm3 = class(TForm)
Button1: TButton;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
SpinEdit1: TSpinEdit;
Memo1: TMemo;
procere Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form3: TForm3;
implementation
uses Unit_Factorial_class;
{$R *.dfm}
var
MyFactorial:TLQM_Factorial_Class;
procere TForm3.Button1Click(Sender: TObject);
var
time1,time2:TTime;
begin
//创建对象
MyFactorial:=TLQM_Factorial_Class.Create;
Label3.Caption:='原数:'+IntToStr(SpinEdit1.Value);
time1:=Time;
//计算
Memo1.Clear;
Memo1.Text:=MyFactorial.FactorialOutput(SpinEdit1.Value);
Time2:=Time;
Label1.Caption:='位数:'+IntToStr(Length(Memo1.Text));
Label2.Caption:='时间:'+TimeToStr(Time2-Time1);
//销毁对象
Myfactorial.Free;
end;
end.
如果计算10000的阶乘,时间约为9秒。
热心网友
时间:2024-11-14 06:32
var a:array [1..10000] of longint;
i,j,k,l,p,o,q,x,y,w:integer;
begin
readln(i);
a[1]:=1;
w:=1;
for j:=1 to i do
begin y:=0;
x:=j;
while x>0 do
begin y:=y+1;
x:=x div 10;
end;
o:=0;
for k:=w to l+y+1 do
begin
q:=a[k]*j+o;
o:=q div 10;
a[k]:=q mod 10;
end;
l:=10000;
while (a[l]=0) and (l>1) do l:=l-1;
w:=1;
while (a[w]=0) and (w<9999) do w:=w+1;
end;
for p:=l downto 1 do
write(a[p]);
writeln;
end.