大数阶乘算法 http://www.delphibbs.com/delphibbs/dispq.asp?lid=494104组合的算法 function combine(A:array of integer; m:integer;var SL:TStrings):integer; //C(n,m) //SL为输出列var total:integer; order:array of integer; count:integer; k:integer; flag:boolean; i:integer; str:string; begin total:=high(A)-low(A)+1; SetLength(order,m+1); order[0]:=-1; count:=0; k:=m; flag:=true; SL.Clear; for i:=1 to m do order[i]:=i; while order[0]=-1 do begin if flag then begin str:=''; for i:=1 to m do str:=str+inttostr(A[order[i]-1]); SL.add(str); inc(count); flag:=false; end; inc(order[k]); if order[k]=(total+1) then begin order[k]:=0; dec(k); continue; end; if k<m then begin inc(k); order[k]:=order[k-1]; continue; end; if k=m then flag:=true; end; result:=count; end;排列算法:这个比较容易,每位分别取不同值就可以了
unit Unit1;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Math;type Arrint = Array of Int64; TForm1 = class(TForm) Button1: TButton; Memo1: TMemo; Edit1: TEdit; procedure Button1Click(Sender: TObject); private aResult : Arrint; iMax, iZeroNO : Int64; { Private declarations } procedure factorial(iNum : Integer); procedure ReCarry(iAdd : Int64; jNum : Integer); procedure ShowResul; public { Public declarations } end;var Form1: TForm1;implementation{$R *.dfm}{ TForm1 }procedure TForm1.factorial(iNum: Integer); var i, j, iLength : Integer; iTmp, iMul : Int64; begin SetLength(aResult,1); aResult[0] := 1; iZeroNO := 0; for i:=2 to iNum do begin iLength := Length(aResult); for j:=iLength-1 downto 0 do begin if aResult[j]<=(iMax div i) then begin aResult[j] := aResult[j] * i; end else begin iMul := aResult[j] * i; aResult[j] := iMul mod iMax; iTmp := iMul div iMax; ReCarry(iTmp,j); //处理有进位(包括多次进位)的情况递归算法 end; end; // end; //iNum 循环结束 end;procedure TForm1.Button1Click(Sender: TObject); var i : integer; iTmp, iNO : int64; tTime1, tTime2 : TTime; sTmp : String; begin iTmp := High(Int64) div 1000; iNO :=1; for i:=1 to Length(IntToStr(iTmp))-1 do begin iNO := iNO * 10; end; iMax := iNO; i := StrToInt(Edit1.Text); tTime1 := Now; factorial(i); tTime2 := Now; ShowResul; sTmp := FormatDateTime('hh:nn:ss:zz',tTime1-tTime2); sTmp := '计算共用时:'+sTmp; Application.MessageBox(pChar(sTmp),'提示',MB_ICONINFORMATION); end;procedure TForm1.ReCarry(iAdd : Int64; jNum: Integer); var iTmp : Int64; iLength : Integer; begin iLength := Length(aResult); if jNum=iLength-1 then begin SetLength(aResult,iLength+1); aResult[jNum+1] := iAdd; end else begin iTmp := iAdd+aResult[jNum+1]; if iTmp>iMax then begin aResult[jNum+1] := iTmp mod iMax; ReCarry(iTmp div iMax,jNum+1); end else aResult[jNum+1] := aResult[jNum+1] + iAdd; end; end;procedure TForm1.ShowResul; var iTmp, i, j : Integer; sTmp : String; sResult : WideString; begin Memo1.Clear; sResult := ''; iTmp := Length(aResult); for i:=iTmp-1 downto 0 do begin if aResult[i]<>0 then begin sTmp := IntToStr(aResult[i]); if (Length(sTmp)=(Length(IntToStr(iMax))-1)) then sResult := sResult + sTmp else begin if i=iTmp-1 then begin sResult := sResult + sTmp; Continue; end; for j:=1 to (Length(IntToStr(iMax))-1-Length(sTmp)) do begin sTmp := '0' + sTmp; end; sResult := sResult + sTmp; end; end else iZeroNO := iZeroNO + Length(IntToStr(iMax)) - 1; end; sTmp := ''; for i:=1 to iZeroNO do sTmp := sTmp + '0'; sResult := sResult + sTmp; Memo1.Lines.Add(sResult); end; end.
上面的算法是我前几天写的,还有一个用链表结构实现的算法。在上面的算法中只要改动iTmp := High(Int64) div 1000;这句后面的数字如改为10000就可计算9999以内的所有数字的阶乘,依次类推还可以在往上改。
//组合 function Combination(mStrings: TStrings; mStr: string; mLen: Integer): Boolean; { 组合 } procedure fCombination(mLeft, mRight: string); var I: Integer; begin if Length(mLeft) >= mLen then mStrings.Add(mLeft) else for I := 1 to Length(mRight) do fCombination(mLeft + Copy(mRight, I, 1), Copy(mRight, I + 1, MaxInt)); end; begin Result := False; if not Assigned(mStrings) then Exit; mStrings.BeginUpdate; try mStrings.Clear; fCombination('', mStr); finally mStrings.EndUpdate; end; Result := True; end; { Combination }procedure TForm1.FormCreate(Sender: TObject); begin Combination(Memo1.Lines, 'abcdef', 3); end;//排列 function Collocate(mStrings: TStrings; mLength: Integer): Boolean; { 全排列 } procedure pCollocate(mLeft, mRight: string); var I, L: Integer; Temp: string; begin L := Length(mLeft); if L = 0 then begin Temp := ''; for I := 1 to Length(mRight) do Temp := Format('%s a%d', [Temp, Ord(mRight[I])]); Delete(Temp, 1, 1); mStrings.Add(Temp); end else for I := 1 to L do begin Temp := mLeft; Delete(Temp, I, 1); pCollocate(Temp, mRight + mLeft[I]); end; end; var S: string; I: Integer; begin Result := False; if not Assigned(mStrings) then Exit; S := ''; for I := 1 to mLength do S := S + Chr(I); mStrings.BeginUpdate; try mStrings.Clear; pCollocate(S, ''); finally mStrings.EndUpdate; end; Result := True; end; { Collocate } procedure TForm1.Button1Click(Sender: TObject); begin Collocate(Memo1.Lines, StrToIntDef(Edit1.Text, 0)); end;
用Google去找找大数运算吧http://lysoft.7u7.net
http://www.delphibbs.com/delphibbs/dispq.asp?lid=494104组合的算法
function combine(A:array of integer; m:integer;var SL:TStrings):integer;
//C(n,m)
//SL为输出列var
total:integer;
order:array of integer;
count:integer;
k:integer;
flag:boolean;
i:integer;
str:string;
begin
total:=high(A)-low(A)+1;
SetLength(order,m+1);
order[0]:=-1;
count:=0;
k:=m;
flag:=true;
SL.Clear;
for i:=1 to m do
order[i]:=i;
while order[0]=-1 do
begin
if flag then
begin
str:='';
for i:=1 to m do
str:=str+inttostr(A[order[i]-1]);
SL.add(str);
inc(count);
flag:=false;
end;
inc(order[k]); if order[k]=(total+1) then
begin
order[k]:=0;
dec(k);
continue;
end; if k<m then
begin
inc(k);
order[k]:=order[k-1];
continue;
end; if k=m then
flag:=true;
end; result:=count;
end;排列算法:这个比较容易,每位分别取不同值就可以了
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Math;type Arrint = Array of Int64; TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
Edit1: TEdit;
procedure Button1Click(Sender: TObject);
private
aResult : Arrint;
iMax, iZeroNO : Int64;
{ Private declarations }
procedure factorial(iNum : Integer);
procedure ReCarry(iAdd : Int64; jNum : Integer);
procedure ShowResul;
public
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.dfm}{ TForm1 }procedure TForm1.factorial(iNum: Integer);
var
i, j, iLength : Integer;
iTmp, iMul : Int64;
begin
SetLength(aResult,1);
aResult[0] := 1;
iZeroNO := 0;
for i:=2 to iNum do
begin
iLength := Length(aResult);
for j:=iLength-1 downto 0 do
begin
if aResult[j]<=(iMax div i) then
begin
aResult[j] := aResult[j] * i;
end
else
begin
iMul := aResult[j] * i;
aResult[j] := iMul mod iMax;
iTmp := iMul div iMax;
ReCarry(iTmp,j); //处理有进位(包括多次进位)的情况递归算法
end;
end; //
end; //iNum 循环结束
end;procedure TForm1.Button1Click(Sender: TObject);
var
i : integer;
iTmp, iNO : int64;
tTime1, tTime2 : TTime;
sTmp : String;
begin
iTmp := High(Int64) div 1000;
iNO :=1;
for i:=1 to Length(IntToStr(iTmp))-1 do
begin
iNO := iNO * 10;
end;
iMax := iNO;
i := StrToInt(Edit1.Text);
tTime1 := Now;
factorial(i);
tTime2 := Now;
ShowResul;
sTmp := FormatDateTime('hh:nn:ss:zz',tTime1-tTime2);
sTmp := '计算共用时:'+sTmp;
Application.MessageBox(pChar(sTmp),'提示',MB_ICONINFORMATION);
end;procedure TForm1.ReCarry(iAdd : Int64; jNum: Integer);
var
iTmp : Int64;
iLength : Integer;
begin
iLength := Length(aResult);
if jNum=iLength-1 then
begin
SetLength(aResult,iLength+1);
aResult[jNum+1] := iAdd;
end
else
begin
iTmp := iAdd+aResult[jNum+1];
if iTmp>iMax then
begin
aResult[jNum+1] := iTmp mod iMax;
ReCarry(iTmp div iMax,jNum+1);
end
else
aResult[jNum+1] := aResult[jNum+1] + iAdd;
end;
end;procedure TForm1.ShowResul;
var
iTmp, i, j : Integer;
sTmp : String;
sResult : WideString;
begin
Memo1.Clear;
sResult := '';
iTmp := Length(aResult);
for i:=iTmp-1 downto 0 do
begin
if aResult[i]<>0 then
begin
sTmp := IntToStr(aResult[i]);
if (Length(sTmp)=(Length(IntToStr(iMax))-1)) then
sResult := sResult + sTmp
else
begin
if i=iTmp-1 then
begin
sResult := sResult + sTmp;
Continue;
end;
for j:=1 to (Length(IntToStr(iMax))-1-Length(sTmp)) do
begin
sTmp := '0' + sTmp;
end;
sResult := sResult + sTmp;
end;
end
else
iZeroNO := iZeroNO + Length(IntToStr(iMax)) - 1;
end;
sTmp := '';
for i:=1 to iZeroNO do
sTmp := sTmp + '0';
sResult := sResult + sTmp;
Memo1.Lines.Add(sResult);
end;
end.
function Combination(mStrings: TStrings; mStr: string;
mLen: Integer): Boolean; { 组合 }
procedure fCombination(mLeft, mRight: string);
var
I: Integer;
begin
if Length(mLeft) >= mLen then
mStrings.Add(mLeft)
else for I := 1 to Length(mRight) do
fCombination(mLeft + Copy(mRight, I, 1), Copy(mRight, I + 1, MaxInt));
end;
begin
Result := False;
if not Assigned(mStrings) then Exit;
mStrings.BeginUpdate;
try
mStrings.Clear;
fCombination('', mStr);
finally
mStrings.EndUpdate;
end;
Result := True;
end; { Combination }procedure TForm1.FormCreate(Sender: TObject);
begin
Combination(Memo1.Lines, 'abcdef', 3);
end;//排列
function Collocate(mStrings: TStrings; mLength: Integer): Boolean; { 全排列 }
procedure pCollocate(mLeft, mRight: string);
var
I, L: Integer;
Temp: string;
begin
L := Length(mLeft);
if L = 0 then
begin
Temp := '';
for I := 1 to Length(mRight) do
Temp := Format('%s a%d', [Temp, Ord(mRight[I])]);
Delete(Temp, 1, 1);
mStrings.Add(Temp);
end else for I := 1 to L do begin
Temp := mLeft;
Delete(Temp, I, 1);
pCollocate(Temp, mRight + mLeft[I]);
end;
end;
var
S: string;
I: Integer;
begin
Result := False;
if not Assigned(mStrings) then Exit;
S := '';
for I := 1 to mLength do S := S + Chr(I);
mStrings.BeginUpdate;
try
mStrings.Clear;
pCollocate(S, '');
finally
mStrings.EndUpdate;
end;
Result := True;
end; { Collocate }
procedure TForm1.Button1Click(Sender: TObject);
begin
Collocate(Memo1.Lines, StrToIntDef(Edit1.Text, 0));
end;