سلام
الگوریتم یا ترجیحا برنامه دلفی 7 می خوام که بشه فاکتوریل عدد بزرگی مثل n را بدست آورد
سلام
الگوریتم یا ترجیحا برنامه دلفی 7 می خوام که بشه فاکتوریل عدد بزرگی مثل n را بدست آورد
اگه اعدادت از یه حدی بزرگتر باشه هیچ الگوریتم موثری واسه این کار نیست، در عوض یه فرمول تجربی هستش که میتونی از کتاب "ریاضیات گسسته و ترکیبیاتی" اثر "رالف پ گریمالدی" درش بیاری. من هم دوباره کتاب رو میگردم، اگه دیدمش واست میفرستم.
function Multi(N1,N2:String):string;
Var
Ma1, Ma2 : array [1..20] of integer;
Ans : array [1..40] of integer;
sum, mult,q:Integer;
N1sign,N2sign: boolean;
begin
N1sign:=false; N2sign:=false;
for q:=1 to length(n1) do
if ord(n1[q]) in [128..137] then n1[q]:=chr(ord(n1[q]&# 41;-80);
for q:=1 to length(n2) do
if ord(n2[q]) in [128..137] then n2[q]:=chr(ord(n2[q]&# 41;-80);
if (length(n1)>20) or (length(n2)>20) then
begin Multi:='0' ; exit end;
if (pos('/',N1)<>0)or(pos('.',N1)< >0)or(pos('/',N2)<>0)or(pos('.',N2)< >0) then
begin Multi:='0' ; exit end;
if n1[1]='+' then delete(n1,1,1)
else if n1[1]='-' then begin delete(n1,1,1) ; N1sign:=true end;
if n2[1]='+' then delete(n2,1,1)
else if n2[1]='-' then begin delete(n2,1,1) ; N2sign:=true end;
for q:=1 to 20 do
if n1[1]='0' then delete(n1,1,1)
else q:=20;
for q:=1 to 20 do
if n2[1]='0' then delete(n2,1,1)
else q:=20;
For I:=1 to 20 do begin Ma1[i]:=0; Ma2[i]:=0; end;
For I:=1 to 40 do begin Ans[i]:=0; end;
Mult:=0;Sum:=0;
for i := 1 to length(N1) do
Ma1 [ i] := ord(N1[length(N1) - i + 1]) - ord( '0' );
for i := 1 to length(N2) do
Ma2 [ i] := ord(N2[length(N2) - i + 1]) - ord ( '0' );
for i := 1 to length(N2) do
for j := 1 to length(N1) do
begin
mult := Ma2[ i] * Ma1[ j];
sum := Ans[ i + j -1] + mult mod 10;
Ans [ i + j -1 ] := sum mod 10;
Ans [ i +j ] := (sum div 10 + Ans [ i + j ] + mult div 10 );
for k := i + j + 1 to length(N1)+length(N2) do
begin
Ans [ k] := Ans [ k] + Ans [ k - 1] div 10;
Ans [ k -1] := Ans [ k - 1] mod 10;
end;
end;
i := length(N1) + length(N2);
N1:=''; N2:='';
while i<>0 do
begin
Str(Ans[i],N2);
N1:=N1+N2; dec(i);
end;
If N1Sign Xor N2Sign then
Insert ('-',N1,1);
If N1[1]='0' then Delete(N1,1,1);
Multi:=N1;
end; { Multiply}
قبلا" این موضوع مورد بحث قرار گرفته.
http://www.barnamenevis.org/viewtopic.php?t=2180
جسارتا خدمت Delphi Area عزیز
الگوریتمی که تو اون تاپیک بود، به هر حال منجر به ضرب 200 عدد در هم میشد که به هر حال بسیار کند است. برای محاسبه فاکتوریل های اعداد بزرگ بهترین راه، همان استفاده از روابط تقریبی است. ( با توجه به اینکه حتی عددی مثل !40 به طرز سرسام آوری بزرگ است و ارزش ارقام سمت راستی آن کم)
با سلام
من 3 سال پیش برنامه ای به زبان دلفی نوشتم که فاکتوریل اعداد بزرگ را حساب می کند.
مثلا برای N=1000 در عرض کمتر از 1 ثانیه جواب می دهد. حتی من فاکتوریل عدد N=100000 را هم حساب کردم .
این برنامه سریع هم هست .ضمنا فاکتوریل را کامل حساب می کند. یعنی تمام ارقام آن را محاسبه و نمایش می دهد . برنامه را با Delphi 5 نوشتم . اگر Source این برنامه را می خواهید بگویید تا برایتان mail کنم .
موفق باشید .
سلام
من سال پیش یک برنامه با وی بی نوشتم که این کار رو انجام میده
ولی سرعتش خیلی خوب نیست و حافظهی زیادی استفاده میکنه مخصوصا برای اعداد خیلی بزرگ
:چون از یک روش بازگشتی استفاده میکنه به این صورت که
فاکتوریل هر عدد برابر با خود عدد ضرب در فاکتوریل عدد قبلی
که مشخصه که برای یک عدد بزرگ سرعت محاسبه پایینه و حافظهی زیادی هم مصرف میشه
من دلفی بلد نیستم ولی ممنون میشم اگه فرشاد بگه که از چه روشی استفاده کرده
خیلی ممنون
:roll: :wink:
با سلام.می تونید sourceو فایل اجرایی برنامه رو از اینجا download کنید :
http://www.barnamenevis.org/vi...amp;highlight=
سورس برنامه در فایل unit1.pas است.
من از لیست پیوندی استفاده کرده ام .ابتدا یک record که معادل struct در C است تعریف کرده ام :
type
MyPointer = ^MyRecord;
Myrecord = Record
ID : Byte ;
Link : MyPointer;
end;
بعد کار شروع میشه :
procedure TForm1.MyPro;
var i : Integer;
begin
new(p);
q := p;
s := p;
p^.ID := 1;
q^.Link := nil;
for i := 1 to N do
Mult(i);
end;
که با استفاده از حلقه عمل می کند .
تابع اصلی هم که کار ضرب را انجام می دهد :
procedure TForm1.Mult ( i : Integer);
var
DahBarYek : Integer;
M : Integer;
begin
DahBarYek := 0;
p := s;
while(p<>q) do
begin
M := i * p^.ID;
p^.ID := (M + DahBarYek)mod 10;
DahBarYek := (DahBarYek + M)div 10;
p := p^.Link;
end;
M := p^.ID * i;
p^.ID := (DahBarYek + M) mod 10;
DahBarYek := (DahBarYek + M) div 10;
while DahBarYek <>0 do
begin
new(q);
p^.Link := q;
q^.ID := DahBarYek mod 10;
p := q;
DahBarYek := DahBarYek div 10;
end;
q^.Link := nil;
end;
نمی دونم چه توضیحی بدم. امیدوارم سورس برنامه قابل درک باشد . اما اگر سوالی داشته باشید من در خدمتم .
بهتره یه نگاه به فرمول استرلینگ بندازی. :flower:
پیشنهاد می کنم به این قسمت هم یه نگاهی بندازید:
http://www.barnamenevis.org/viewtopic.php?t=13980
:embr:
من این برنامه رو به زبان c نوشتم
راهت می تونی الگوریتمشو تو delphi پیاده سازس کنی تا 4000 رو برات محاسبه می کنه اگه بیشتر باشه طول آرایه رو زیاد کن
#include <iostream.h>
#include <conio.h>
#include <stdlib.h>
#include <stdio.h>
main()
{
int m[4000],i,num;
long double fact;
for(i=1;i<4000;i++)
m[i]=i;
cout<<"please enter your number for Fact";
cin>>num;
fact=1;
for(i=1;i<=num;i++)
fact=fact*m[i];
cout<<fact;
getch();
return 0;
}
دلیل اینکه اعداد 1 تا (طول آرایه) رو ریختین توی آرایه و بعد اونها رو تا num با هم ضرب کردین چیه؟! خوب از همون اول iهای از 1 تا num رو به جای m[i]ها در هم ضرب کنید! هوم؟!نوشته شده توسط powerboy2988
ضمن اینکه فکر نکنم این الگوریتم مد نظر کسی باشه چون جواب بصورت عدد علمی(؟!) هست و در واقع کامل نیست! فکر کنم هدف الگوریتمی هست که عدد رو به صورت دقیق نمایش بده!!!
البته احتمالا گفته خواهد شد که توی الگوریتم محدودیتهای سختافزار و نرمافزار و دیگر افزارها نباید مطرح باشه! به نظر من اما قابلیت پیاده سازی رو هم باید در نظر گرفت!!!!