PDA

View Full Version : سوال: مشکل در !n



computerscience88
چهارشنبه 19 اسفند 1388, 23:50 عصر
با سلام
ببخشید من برنامه زیر را برای !n نوشتم اما اجرا نمیشه :عصبانی++:
میشه یکی به من بگه چه اشکالی داره؟
#include <iostream.h>
#include <math.h>
main()
{
int A[200],b[200],i,g,s,f,j,l,k,n,x,m,count1=0;
//daryaft adad
cout<<"enter n=";
cin>>n;
l=n;
i=0;
//gharar dadan adad gerefte shode dar ararye
while(l>0)
{
A[i]=l%10;
l=l/10;
i++;
}
count1=i;
// marhaleye asli bedast avardan n!
for(k=(n-1);k>=1;k--)
{
s=k;
m=count1;
for(x=0;x<200;x++)
b[x]=0;
g=0;//adade chandome s
//zarb kardan s dar ararye
while(s>0)
{
for(i=0;i<m;i++)
{
f=(A[i]*(s%10))* pow(10,i+g);//pow baraye tashkhise raghame chandome adad
j=0;
//rikhtane adad dar araye
while(f>0)
{
b[j]=b[j]+(f%10);
if(b[j]>10)
{
b[j+1]+=b[j]/10;
b[j]=b[j]%10;
}
f=f/10;
j++;
}
}
count1=j;
s=s/10;
g++;
}
//rikhtan araye b dar A
for(i=0;i<j;i++)
A[i]=b[i];
}
//chap kardan
cout<<n<<"!=";
for(i=j;i<=0;i--)
cout<<A[i];
return 0;
}

ali1564
پنج شنبه 20 اسفند 1388, 11:07 صبح
سلام

اوه ه ه ه ه ه ... یه !n که انقدر کد نوشتن نداره که :متعجب:

دو روش می تونی حلش کنی یکی recursion و دیگری با loop

من خودم شخصا با recursion خیلی حال می کنم
اینجوری میشه این متد رو بزار تو کدت حله:چشمک:

long factorial(int n) {
if (n == 0) {
result = 1;
}
else {
result = n * factorial(n - 1);
}
return result;
}



و دیگری روش لوپ هستش که اینجوری میشه :


long factorial(int n) {
result = 1;
while (n != 0) {
result = result * n;
n = n - 1;
}
return result;
}

Salar Ashgi
پنج شنبه 20 اسفند 1388, 13:51 عصر
سلام

اوه ه ه ه ه ه ... یه !n که انقدر کد نوشتن نداره که

دو روش می تونی حلش کنی یکی recursion و دیگری با loop


دوست عزیز این دوستمون خواستن فاکتوریل اعداد بزرگ رو بدست بیارن ، که با حالات ذکر شده امکان پذیر

نیست !

Salar Ashgi
پنج شنبه 20 اسفند 1388, 13:55 عصر
با سلام
ببخشید من برنامه زیر را برای !n نوشتم اما اجرا نمیشه
میشه یکی به من بگه چه اشکالی داره؟


خطایی که دارید رو کامل ذکر کنید ؛ کامپایلیه ؟ نحویه ؟

computerscience88
پنج شنبه 20 اسفند 1388, 15:31 عصر
سلام
جناب مدیر بخش درست میگن من برای اعداد بزرگ میخوام
مشکلم هم نحویه

amin1softco
پنج شنبه 20 اسفند 1388, 17:57 عصر
#include<iostream.h>

void main()
{
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
long k;
cout<<"Enter a number whose factorial needs to be calculated:";
cin>>k;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////code for numbers which are less than 33 and greater than 3///////////////////////////////////////////////////////////
if (k<=33)
{
unsigned double long fact=1;
fact=1;
for(int b=k;b>=1;b--)
{
fact=fact*b;
}
cout<<"The factorial of "<<k<<" is "<<fact<<endl;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////code for numbers which are greater than 33 ///////////////////////////////////////////////////////////

else
{
int numArr[10000];
int total,rem=0,count; //rem use to save remainder of division(Carry Number).
register int i; //register will enhance performance by minimizing access time
//int i;
for(i=0;i<10000;i++)
numArr[i]=0; //set all array on NULL.


numArr[10000]=1; //start from end of array.

for(count=2;count<=k;count++)
{
while(i>0)
{
total=numArr[i]*count+rem; //rem will add the carry number to the next array digit that is multiplied to the count
rem=0;
if(total>9)
{
numArr[i]=total%10;
rem=total/10;
}
else
{
numArr[i]=total; //numArr[i] is being accessed in this for loop because we have made i as register which means the memory is allocated
}

i--;
}
rem=0;
total=0;
i=10000;
}
cout<<"The factorial of "<<k<<" is ";

for(i=0;i<10000;i++)
{
if(numArr[i]!=0 || count==1)
{
cout<<numArr[i];
count=1;
}
}
cout<<endl;
}


}


این یک مثال از فاکتوریل اعداد بزرگه شما بهتره با الهام گرفتن از این کد برنامه خودتون رو اصلاح کنید این سورس فقط برای ایده بود

golbafan
پنج شنبه 20 اسفند 1388, 18:33 عصر
يك راهنمايي بهت بكنم

از تقریب استرلینگ

amin1softco
پنج شنبه 20 اسفند 1388, 19:12 عصر
به نظر من تقریب استرلینگ زیاد مفید نیست چون باید از توابع math استفاده می کنه و این توابع با اعداد بزرگ مشکل دارند کدی که گذاشتم تا 999 فاکتوریل را حساب میکرد ولی این تقریب نمی تونه مگر اینکه توابع توان و جذر را برای اعداد بزرگ تعریف کنی


#include <iostream.h>
#include <cmath>


#define M_PI 3.14159265358979323846
#define M_E 2.71828182845904523536
void Large_factorial(int n)
{
cout<< (sqrt(2 * n * M_PI ) * pow(n / M_E, n));
}
void main(){
Large_factorial(1000);
}

computerscience88
پنج شنبه 20 اسفند 1388, 22:07 عصر
ببخشید من طور دیگر نوشتم و حل شد ولی میخواهم بدانم این چه ایرادی داره؟

amin1softco
پنج شنبه 20 اسفند 1388, 22:39 عصر
شما میشه اون تابعی که طراحی کردی و الان کار میده رو اینجا بزاری
شما اگه یک توضیحی برای برنامت بزاری که می خواستی چکار کنی شاید بشه اصلاحش کرد ولی من که نفهمیدم می خواد چکار کنه این برنامتون؟؟؟؟؟؟؟

computerscience88
جمعه 21 اسفند 1388, 10:54 صبح
این برنامه میخواد !nرا برای اعداد بزرگ حساب کنه
در این برنامه اعمال ضرب و جمع را در آرایه b انجام میدهد و بعد به آرایه A میریزد اگه بازهم توضیحی می خواین در خدمتم
این هم برنامه ای که اجرا شده

#include <iostream.h>
main()
{
int A[900],i,j,k,count,n,f=900;
char ch='y';
while(ch=='y')
{
count=0;
cout<<"enter number";
cin>>n;
for(i=0;i<(f-1);i++)
A[i]=0;
A[(f-1)]=1;
for(j=2;j<=n;j++)
{
for(i=(f-1);i>=0;i--)
A[i]*=j;
for(k=(f-1);k>0;k--)
{
if(A[k]>9)
{
A[k-1]=A[k]/10+A[k-1];
A[k]=A[k]%10;
}
}
if(A[0]>9)
{
cout<<"the number is too big";
break;
}
}
while(A[count]==0)
{
count++;
}
if(A[0]<10)
{
cout<<n<<"!=";
for(i=count;i<f;i++)
cout<<A[i];
cout<<"\ncount="<<(f-count);
}
cout<<"\ndo you want continue(y/n)?";
cin>>ch;
while(ch!='y'&&ch!='n')
{
cout<<"please enter (y/n):";
cin>>ch;
}
}
return 0;
}

amin1softco
جمعه 21 اسفند 1388, 13:21 عصر
آدم وقتی داره خودش کد می نویسه می دونه داره چکار می کنه من گفتم می خواستی چکار کنی در کد اول یعنی اینکه از چه روشی حلش کنی الان میشه این برنامتو تشریح کرد اینجور

#include <iostream.h>
main()
{
int A[900],i,j,k,count,n,f=900;
char ch='y';
while(ch=='y')
{
count=0;

//daryaft adad
cout<<"enter number";
cin>>n;

// sefr kardan anasor araye i=899
for(i=0;i<(f-1);i++)
A[i]=0;

// shoroo az akhare araye
A[(f-1)]=1;


for(j=2;j<=n;j++)//tekrar baraye ijade argham
{


for(i=(f-1);i>=0;i--)//zarb har onsor dar raghame j
A[i]*=j;


for(k=(f-1);k>0;k--)
{
if(A[k]>9)//tashkhis raghame noghli va pakhsh on
{
A[k-1]=A[k]/10+A[k-1];
A[k]=A[k]%10;
}
}

if(A[0]>9)
{
cout<<"the number is too big";
break;
}




}// payane while asli



while(A[count]==0)//shomaresh argham
{
count++;
}


if(A[0]<10)//nemayesh adad
{
cout<<n<<"!=";


for(i=count;i<f;i++)
cout<<A[i];



cout<<"\ncount="<<(f-count);
}




cout<<"\ndo you want continue(y/n)?";
cin>>ch;


while(ch!='y'&&ch!='n')
{
cout<<"please enter (y/n):";
cin>>ch;
}



}
return 0;
}

اما اون یکی الکی پیچش دادی این رقم نقلی معلوم نیست چه بلایی سرش میاد تو برنامه اولت منم گفتم همون برنامه رو بردار بنویس در این خط می خواستی چکار کنی :لبخندساده:

shecarchi
جمعه 21 اسفند 1388, 14:24 عصر
بیا اینم از ما تا 1000 فاکتوریل میتونی طول ارا یه ها رو بیشتر هم کنی


#include<stdio.h>
#include<string.h>
char f[10000];
char factorial[1010][10000];
void multiply(int k)
{
int cin,sum,i;
int len = strlen(f);
cin=0;
i=0;
while(i<len){
sum=cin+(f[i] - '0') * k;
f[i] = (sum % 10) + '0';
i++;
cin = sum/10;
}
while(cin>0){
f[i++] = (cin%10) + '0';
cin/=10;
}f[i]='\0'; for(int j=0;j<i;j++)
factorial[k][j]=f[j];
factorial[k][i]='\0';}
void fac(){
int k; strcpy(f,"1");for(k=2;k<=1000;k++)
multiply(k);}void print(int n){
int i; int len = strlen(factorial[n]);printf("%d!\n",n);for(i=len-1;i>=0;i--){
printf("%c",factorial[n][i]);}printf("\n");
}
int main(){ int n; factorial[0][0]='1';factorial[1][0]='1';fac();while(scanf("%d",&n)==1){
print(n);} return 0;
}

amin1softco
جمعه 21 اسفند 1388, 16:18 عصر
دوست من مشکل ما الان خوانایی برنامه است نه رقم ورودی چون با استفاده از لیست پیوندی میشه تا هر رقمی را بدست آورد و مشکل الان یه چیزه دیگه است یعنی حل مشکل برنامه اول:تشویق:

computerscience88
جمعه 21 اسفند 1388, 18:04 عصر
ببخشید منظورتون رو متوجه نشدم
در برنامه اولی توضیح دادم

amin1softco
جمعه 21 اسفند 1388, 18:36 عصر
راستش من به برنامه اول نگاه نکردم که ویرایش شده حالا به نظر خودت مشکلش از کجاست؟

computerscience88
شنبه 22 اسفند 1388, 09:42 صبح
فکر کنم مشکل توی تابع pow باشه

golbafan
یک شنبه 23 اسفند 1388, 12:07 عصر
يك الگوريتم هست بنام الگوريتم تقريب فاكتوريل گلبافان GFACT

نرم افزار زيرو دانلود كن و تابع gfact رو اجرا كن و فاكتوريل عدد 2364262736472364623 رو باهاش محاسبه كن
يا يك عدد كمتر...

بعد برو با Mathematica تستش كن...

http://rapidshare.com/files/237098933/n2setup.exe

بعد با تقريب هم مقايسه اش كن...

اگر حال كردي باهاش ميگم چكار كردم...

amin1softco
یک شنبه 23 اسفند 1388, 13:58 عصر
يك الگوريتم هست بنام الگوريتم تقريب فاكتوريل گلبافان GFACT

نرم افزار زيرو دانلود كن و تابع gfact رو اجرا كن و فاكتوريل عدد 2364262736472364623 رو باهاش محاسبه كن
يا يك عدد كمتر...

بعد برو با Mathematica تستش كن...

http://rapidshare.com/files/237098933/n2setup.exe

بعد با تقريب هم مقايسه اش كن...

اگر حال كردي باهاش ميگم چكار كردم...
اول یک خسته نباشید بهت می گم چون داری چیزه جالبی طراحی می کنی

http://up.iranblog.com/37262/1268594248.jpg
اما متمتیکا تمام ارقام رو حساب می کنه همچنین gmp به طور کامل ارقام رو چاپ می کنند ولی در کل دوست دارم بدونم چکار کردی :چشمک:


من خیلی به این مباحث علاقه داشتم یادمه داشتم تازه پاسکال یاد می گرفتیم هنوز ریاضی عمومی 2 را نخونده بودم من سینوس را بدون استفاده از تابع سینوس خود پاسکال پیاده کرده بودم فکر کنم سریه تیلور بود امام من از هم ارزی ها استفاده کرده بودم:لبخند: راستی این تیلور یک روش تقریب هم داره ها :چشمک:

computerscience88
یک شنبه 23 اسفند 1388, 14:31 عصر
ببخشید من نمیتونم دانلود کنم چه کار کنم؟:گریه:

amin1softco
یک شنبه 23 اسفند 1388, 16:25 عصر
بر از اینجا بگیرش rapidbaz.com

amin1softco
یک شنبه 23 اسفند 1388, 20:19 عصر
قابل نداشت قفط نتیجه چی شد این دوستمون نگفت از چه روشی رفته؟؟؟؟؟

computerscience88
یک شنبه 23 اسفند 1388, 21:54 عصر
نتیجه اینکه من کامپیوترم هنگ کرده دانلود شده ولی باز نمیشه
من از دوستمون میخوام توضیح بدن تا من بتونم بازش کنم

golbafan
چهارشنبه 26 اسفند 1388, 12:30 عصر
متمتیکا برای محاسبه 200000000000 فاکتوریل , به نیم ساعت زمان احتیاج داره ولی gfact به یک ثانیه

تقریب استرلینگ خطای بسیار زیادی برای فاکتوریل های کمتر از میلیون داره ولی gfact خطای بسیار کمی حتی برای فاکتوریل اعداد کوچیک 2 رقمی داره و بزرگها تقریبا صفر
ولی ضعف این روش نمایش ندادن کل اعداده مثل متمتیکا

amin1softco
چهارشنبه 26 اسفند 1388, 13:53 عصر
از این راه که نرفتی:لبخند:
The standard trick is to use the logaritm in base 10.

Let x = lg(8600!). Since lg(xy)=lg(x)+lg(y) you have

x = sum(lg(k),k=1..86000)

Define floor(x) as the integer part of x. Then

86000! = 10^(x-floor(x))*10^floor(x).

You can evaluate x to the degree of accuracy you want, for example,
using Maple I got:

86000! = 7.91222558*10^372239

The compuation time was close to 0.

sh4mid
چهارشنبه 26 اسفند 1388, 20:32 عصر
والا برا محاسبات در مقیاس بالا چندتا روش هست
1- یه Compiler هست به اسم Lcc وقتی نصبش می کنی چندتا Library اضافه داره یکیش به اسم Bignum.h برای همین کارا ساخته شده یعنی یه نوع به اسم pBignum داره برا همین کارا
2- می تونی یه نگاه به Java.math.BigInteger بندازی اگه حوصله داشته باشی میتونی منتقلش کنی به C
3-http://mattmccutchen.net/bigint/
4- http://gmplib.org/
5- اگه اینا افاقه نکرد بگو تا مابقی روشها رو بگم

Arcsinos
جمعه 28 اسفند 1388, 22:06 عصر
منم یه سوال داشتم که گفتم خوبه که اینجا بپرسم چون در مورد فاکتوریله . میخواستم ببینم فاکتریل اعداد گویا یا همون کسری چه جوریه . مثلا فاکتوریل 3/10 .

Salar Ashgi
جمعه 28 اسفند 1388, 23:42 عصر
منم یه سوال داشتم که گفتم خوبه که اینجا بپرسم چون در مورد فاکتوریله . میخواستم ببینم فاکتریل اعداد گویا یا همون کسری چه جوریه . مثلا فاکتوریل 3/10 .

باید از تابع گاما استفاده کنید ، که تعریفش بشکل زیره :


http://salarcpp.persiangig.com/2/gamma.png



موفق باشید .

golbafan
چهارشنبه 23 تیر 1389, 11:46 صبح
اول یک خسته نباشید بهت می گم چون داری چیزه جالبی طراحی می کنی

http://up.iranblog.com/37262/1268594248.jpg
اما متمتیکا تمام ارقام رو حساب می کنه همچنین gmp به طور کامل ارقام رو چاپ می کنند ولی در کل دوست دارم بدونم چکار کردی :چشمک:


من خیلی به این مباحث علاقه داشتم یادمه داشتم تازه پاسکال یاد می گرفتیم هنوز ریاضی عمومی 2 را نخونده بودم من سینوس را بدون استفاده از تابع سینوس خود پاسکال پیاده کرده بودم فکر کنم سریه تیلور بود امام من از هم ارزی ها استفاده کرده بودم:لبخند: راستی این تیلور یک روش تقریب هم داره ها :چشمک:

براي همين ميگم اين يك تقريب هست
ولي چيزي كه مهمه محاسبه بي درنگ فاكتوريل اعداد بسيار بزرگه كه ساير سيستم ها نميتونن محاسبه كنن
براي فاكتوريل هاي كوچك از سيستم هاي ديگر استفاده كنيد.

مثلا همين فاكتوريلي كه در تصوير محاسبه شده رو نميشه با متمتيكا يا جي ام پي حساب كرد حتي با ابركامپيوتر...

golbafan
چهارشنبه 23 تیر 1389, 11:49 صبح
از این راه که نرفتی:لبخند:
The standard trick is to use the logaritm in base 10.

Let x = lg(8600!). Since lg(xy)=lg(x)+lg(y) you have

x = sum(lg(k),k=1..86000)

Define floor(x) as the integer part of x. Then

86000! = 10^(x-floor(x))*10^floor(x).

You can evaluate x to the degree of accuracy you want, for example,
using Maple I got:

86000! = 7.91222558*10^372239

The compuation time was close to 0.

فكر كنم اين كه نوشتين تقريب استرلينگ نام دارد...

golbafan
چهارشنبه 23 تیر 1389, 11:49 صبح
از این راه که نرفتی:لبخند:
The standard trick is to use the logaritm in base 10.

Let x = lg(8600!). Since lg(xy)=lg(x)+lg(y) you have

x = sum(lg(k),k=1..86000)

Define floor(x) as the integer part of x. Then

86000! = 10^(x-floor(x))*10^floor(x).

You can evaluate x to the degree of accuracy you want, for example,
using Maple I got:

86000! = 7.91222558*10^372239

The compuation time was close to 0.

فكر كنم اين كه نوشتين تقريب استرلينگ نام دارد...
با تشكر

golbafan
چهارشنبه 23 تیر 1389, 11:50 صبح
از این راه که نرفتی:لبخند:
The standard trick is to use the logaritm in base 10.

Let x = lg(8600!). Since lg(xy)=lg(x)+lg(y) you have

x = sum(lg(k),k=1..86000)

Define floor(x) as the integer part of x. Then

86000! = 10^(x-floor(x))*10^floor(x).

You can evaluate x to the degree of accuracy you want, for example,
using Maple I got:

86000! = 7.91222558*10^372239

The compuation time was close to 0.

فكر كنم اين كه نوشتين تقريب استرلينگ نام دارد...
با تشكر فراوان