PDA

View Full Version : فاکتوریل عدد n



Developer Programmer
سه شنبه 23 دی 1382, 13:38 عصر
سلام
الگوریتم یا ترجیحا برنامه دلفی 7 می خوام که بشه فاکتوریل عدد بزرگی مثل n را بدست آورد

Sepidar
سه شنبه 23 دی 1382, 15:51 عصر
اگه اعدادت از یه حدی بزرگتر باشه هیچ الگوریتم موثری واسه این کار نیست، در عوض یه فرمول تجربی هستش که میتونی از کتاب "ریاضیات گسسته و ترکیبیاتی" اثر "رالف پ گریمالدی" درش بیاری. من هم دوباره کتاب رو میگردم، اگه دیدمش واست میفرستم.

JavanSoft
چهارشنبه 24 دی 1382, 13:20 عصر
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])-80);
for q:=1 to length(n2) do
if ord(n2[q]) in [128..137] then n2[q]:=chr(ord(n2[q])-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}

Kambiz
چهارشنبه 24 دی 1382, 23:49 عصر
قبلا" این موضوع مورد بحث قرار گرفته.
http://www.barnamenevis.org/forum/viewtopic.php?t=2180

Sepidar
جمعه 26 دی 1382, 05:09 صبح
جسارتا خدمت Delphi Area عزیز

الگوریتمی که تو اون تاپیک بود، به هر حال منجر به ضرب 200 عدد در هم میشد که به هر حال بسیار کند است. برای محاسبه فاکتوریل های اعداد بزرگ بهترین راه، همان استفاده از روابط تقریبی است. ( با توجه به اینکه حتی عددی مثل !40 به طرز سرسام آوری بزرگ است و ارزش ارقام سمت راستی آن کم)

Farshad Paydar
شنبه 27 تیر 1383, 07:23 صبح
با سلام
من 3 سال پیش برنامه ای به زبان دلفی نوشتم که فاکتوریل اعداد بزرگ را حساب می کند.
مثلا برای N=1000 در عرض کمتر از 1 ثانیه جواب می دهد. حتی من فاکتوریل عدد ‌N=100000 را هم حساب کردم .
این برنامه سریع هم هست .ضمنا فاکتوریل را کامل حساب می کند. یعنی تمام ارقام آن را محاسبه و نمایش می دهد . برنامه را با Delphi 5 نوشتم . اگر Source این برنامه را می خواهید بگویید تا برایتان mail کنم .
موفق باشید .

Ali_mx
جمعه 20 شهریور 1383, 11:07 صبح
سلام
من سال پیش یک برنامه با وی بی نوشتم که این کار رو انجام میده
ولی سرعتش خیلی خوب نیست و حافظه‌ی زیادی استفاده میکنه مخصوصا برای اعداد خیلی بزرگ
:چون از یک روش بازگشتی استفاده میکنه به این صورت که
فاکتوریل هر عدد برابر با خود عدد ضرب در فاکتوریل عدد قبلی
که مشخصه که برای یک عدد بزرگ سرعت محاسبه پایینه و حافظه‌ی زیادی هم مصرف میشه
من دلفی بلد نیستم ولی ممنون میشم اگه فرشاد بگه که از چه روشی استفاده کرده
خیلی ممنون
:roll: :wink:

Farshad Paydar
شنبه 21 شهریور 1383, 08:04 صبح
با سلام.می تونید sourceو فایل اجرایی برنامه رو از اینجا download کنید :
http://www.barnamenevis.org/forum/viewtopic.php?t=12488&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;

نمی دونم چه توضیحی بدم. امیدوارم سورس برنامه قابل درک باشد . اما اگر سوالی داشته باشید من در خدمتم .

hooshmand_mostafa
سه شنبه 24 آذر 1383, 12:31 عصر
بهتره یه نگاه به فرمول استرلینگ بندازی. :flower:

MSK
سه شنبه 01 دی 1383, 17:19 عصر
پیشنهاد می کنم به این قسمت هم یه نگاهی بندازید:

http://www.barnamenevis.org/forum/viewtopic.php?t=13980

:embr:

powerboy2988
جمعه 05 آبان 1385, 12:03 عصر
من این برنامه رو به زبان 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;
}

ashoob
یک شنبه 07 آبان 1385, 09:42 صبح
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];

دلیل اینکه اعداد 1 تا (طول آرایه) رو ریختین توی آرایه و بعد اونها رو تا num با هم ضرب کردین چیه؟! خوب از همون اول iهای از 1 تا num رو به جای m[i]ها در هم ضرب کنید! هوم؟!
ضمن اینکه فکر نکنم این الگوریتم مد نظر کسی باشه چون جواب بصورت عدد علمی(؟!) هست و در واقع کامل نیست! فکر کنم هدف الگوریتمی هست که عدد رو به صورت دقیق نمایش بده!!!
البته احتمالا گفته خواهد شد که توی الگوریتم محدودیت‌های سخت‌افزار و نرم‌افزار و دیگر افزارها نباید مطرح باشه! به نظر من اما قابلیت پیاده سازی رو هم باید در نظر گرفت!!!!

Malakootee
جمعه 31 خرداد 1387, 16:11 عصر
من این برنامه رو به زبان 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;
}




من این رو واسه دلفی نوشتم ولی باز هم جواب نداد. 171! رو نمیتونه حساب کنه. فقط تا 170 جواب میده. :افسرده::افسرده::افسرده::افس ده: