نمایش نتایج 1 تا 13 از 13

نام تاپیک: فاکتوریل عدد n

  1. #1

    فاکتوریل عدد n

    سلام
    الگوریتم یا ترجیحا برنامه دلفی 7 می خوام که بشه فاکتوریل عدد بزرگی مثل n را بدست آورد

  2. #2
    اگه اعدادت از یه حدی بزرگتر باشه هیچ الگوریتم موثری واسه این کار نیست، در عوض یه فرمول تجربی هستش که میتونی از کتاب "ریاضیات گسسته و ترکیبیاتی" اثر "رالف پ گریمالدی" درش بیاری. من هم دوباره کتاب رو میگردم، اگه دیدمش واست میفرستم.

  3. #3

    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}

  4. #4
    کاربر دائمی
    تاریخ عضویت
    مرداد 1382
    محل زندگی
    تهران
    پست
    484
    قبلا" این موضوع مورد بحث قرار گرفته.
    http://www.barnamenevis.org/viewtopic.php?t=2180

  5. #5
    جسارتا خدمت Delphi Area عزیز

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

  6. #6

    پاسخ مثبت

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

  7. #7
    سلام
    من سال پیش یک برنامه با وی بی نوشتم که این کار رو انجام میده
    ولی سرعتش خیلی خوب نیست و حافظه‌ی زیادی استفاده میکنه مخصوصا برای اعداد خیلی بزرگ
    :چون از یک روش بازگشتی استفاده میکنه به این صورت که
    فاکتوریل هر عدد برابر با خود عدد ضرب در فاکتوریل عدد قبلی
    که مشخصه که برای یک عدد بزرگ سرعت محاسبه پایینه و حافظه‌ی زیادی هم مصرف میشه
    من دلفی بلد نیستم ولی ممنون میشم اگه فرشاد بگه که از چه روشی استفاده کرده
    خیلی ممنون
    :roll: :wink:

  8. #8
    با سلام.می تونید 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;

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

  9. #9
    بهتره یه نگاه به فرمول استرلینگ بندازی. :flower:

  10. #10
    کاربر دائمی آواتار MSK
    تاریخ عضویت
    تیر 1383
    محل زندگی
    فعلا تهران - بعدا خدا می‌دونه!
    پست
    331
    پیشنهاد می کنم به این قسمت هم یه نگاهی بندازید:

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

    :embr:

  11. #11
    کاربر دائمی آواتار powerboy2988
    تاریخ عضویت
    تیر 1385
    محل زندگی
    تهران
    سن
    37
    پست
    1,301
    من این برنامه رو به زبان 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;
    }

  12. #12
    نقل قول نوشته شده توسط powerboy2988
    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]ها در هم ضرب کنید! هوم؟!
    ضمن اینکه فکر نکنم این الگوریتم مد نظر کسی باشه چون جواب بصورت عدد علمی(؟!) هست و در واقع کامل نیست! فکر کنم هدف الگوریتمی هست که عدد رو به صورت دقیق نمایش بده!!!
    البته احتمالا گفته خواهد شد که توی الگوریتم محدودیت‌های سخت‌افزار و نرم‌افزار و دیگر افزارها نباید مطرح باشه! به نظر من اما قابلیت پیاده سازی رو هم باید در نظر گرفت!!!!

  13. #13
    کاربر تازه وارد آواتار Malakootee
    تاریخ عضویت
    خرداد 1387
    محل زندگی
    Mashad
    پست
    48

    Exclamation نقل قول: فاکتوریل عدد n

    نقل قول نوشته شده توسط powerboy2988 مشاهده تاپیک
    من این برنامه رو به زبان 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 جواب میده.

برچسب های این تاپیک

قوانین ایجاد تاپیک در تالار

  • شما نمی توانید تاپیک جدید ایجاد کنید
  • شما نمی توانید به تاپیک ها پاسخ دهید
  • شما نمی توانید ضمیمه ارسال کنید
  • شما نمی توانید پاسخ هایتان را ویرایش کنید
  •