PDA

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



shabahang elmian
یک شنبه 08 شهریور 1383, 15:09 عصر
سلام
در ادامه بحث فاکنوریل ، یک پیشنهاد دارم .
شاید بشه الگوریتم بیان شده توسط مدیر محترم گروه رو اینجوری کامل کنیم که یک فیلد عددی برای ذخیره تعداد صفر های سمت راست عدد حاصلضرب داشته باشیم .اینجوری میشه این صفرها رو(که کم هم نیستند مثلا 49 تا صفر برای 200!) از چرخه ضرب خارج کرد برای برسی صفر های سمت راست نیز هر 5 ضرب یکبار باید عمل کنیم .
به این صورت الگوریتم خیلی سریعتر میشه
لطفا نظرتون رو بگید
لینک مطلب قبلی :http://www.barnamenevis.org/forum/viewtopic.php?t=6147

hooshmand_mostafa
جمعه 27 آذر 1383, 13:33 عصر
ما که نفهمیدیم چی گفتی؟ :گیج:
میشه بیشتر توضیح بدی.

MSK
سه شنبه 01 دی 1383, 16:17 عصر
سریع ترین روش برای پیدا کردن تعداد صفرهای یک عدد این است:
1. بزرگترین توان 5 که از عدد مورد نظر کوچکتر است را پیدا کنیم.
2. عدد زیر برابر تعداد صفر هاست:
[x/5]+[x/25]+...+[x/5^n]

توجه شود که [] همان جز صحیح عدد و x نیز همان عدد است.
به هر حال ایده شما ایده خیلی خوبه ولی بیش از اینکه سرعت رو افزایش بده طول جواب رو کاهش میده. :موفق:

چندی پیش من هم همچین برنامه ای نوشته بودم که وقتی با متمتیکا مقایسه کردمش برنامه من تاحدودی سریع تر بود!
بهرحال اگر کدش رو پیدا کردم اینجا قرار میدمش.

MSK
سه شنبه 01 دی 1383, 16:36 عصر
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ComCtrls, XPMan;

type
TForm1 = class(TForm)
Edit1: TEdit;
Label1: TLabel;
Memo1: TMemo;
Button1: TButton;
XPManifest1: TXPManifest;
ProgressBar1: TProgressBar;
Label2: TLabel;
Time: TLabel;
Label3: TLabel;
Digit: TLabel;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
p:array[1..100000000]of byte;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
f,i,b:longword;
myf:integer;
t1:longword;

{$Hints OFF}
procedure comp(a:longword);
var
point,mulres,addbuf:longword;
begin
point:=1;
mulres:=0;
addbuf:=0;
while (addbuf<>0)or(p[point]<>10) do
begin
mulres:=a*(p[point] mod 10);
mulres:=mulres+addbuf;
addbuf:=mulres div 10;
p[point]:=mulres mod 10;
inc(point);
end;
end;
{$Hints ON}

begin
t1:=gettickcount;
fillchar(p,100000000,10);
p[1]:=1;
f:=strtoint(edit1.Text);
for i:=2 to f do begin
comp(i);
progressbar1.Position:=round(i/f*100);
end;
i:=100000000;
while p[i]=10 do dec(i);
myf:=filecreate('Buf.Dat');
for f:=1 to i do inc(p[f],$30);
for f:=1 to i div 2 do begin
b:=p[f];
p[f]:=p[i-f+1];
p[i-f+1]:=b;
end;
filewrite(myf,p,i);
fileclose(myf);
memo1.Lines.LoadFromFile('Buf.Dat');
t1:=gettickcount-t1;
time.Caption:=inttostr(t1);
digit.Caption:=inttostr(i);
end;

end.

دقیقا اطمینان ندارم که همین بود!

بهرحال چون این برنامه فرم هم داشته شما باید کنترل های مورد نیاز رو بهش اضافه کنید یا برنامه رو تغییر بدید.
فکر می کنم 1 ملیون فاکتوریل رو هم بگیره ولی بیش از 100 هزار فاکتوریل رو امتحان نکن چون خیلی معطل میشی واگر سیستمت ضعیف باشه با بیش از حد ازش کار بکشی هنگ می کنه چون برنامه واقعا همه سی پی یو رو به خودش اختصاص میده و نمیشه کنسلش کرد. :strange: