من فکر کردم قراره از مرکز خونه ها حرکت کنه نه از روی مرز ها.
پس توی کدی که گذاشتم من تعداد حرکت ها رو N-1 و M-1 گذاشتم که باید بجاش M و N میگذاشتم:
[/SIZE]کد:برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
من فکر کردم قراره از مرکز خونه ها حرکت کنه نه از روی مرز ها.
پس توی کدی که گذاشتم من تعداد حرکت ها رو N-1 و M-1 گذاشتم که باید بجاش M و N میگذاشتم:
[/SIZE]کد:برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
توابع بازگشتی هست دیگه.توی کد تابع findWays خودش رو صدا میزنه.اصلا بعید میدونم بدون توابع بازگشتی بشه برای هر M و N ی نوشتش.مثلا اگه M و N خیلی زیاد باشن و نخوای از بازگشتی استفاده کنی باید تعداد زیادی for بگذاری که اصلا معقول نیست..
انصافا برای درس شما سوال سختی هست معلومه استاد سخت گیری دارینولی اگه صورت مساله رو کامل درک کنی و مفهوم تابع بازگشتی رو بفهمی میتونی راحت بنویسیش.
هر مرحله رو توی یک خط مینویسه منتها به حالت درختی(چون نخواستم آرایه بگذارم) یعنی مثلا برای 3 در 3 خروجی این هست :
که اولین مسیر میشه R R R D D D دومی میشه R R D R D D که دو مرحله ی اول مسیر دوم(R R) نوشته نشده چون عینا توی مسیر اول هست.کد:برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
مسیر سوم میشه R R D D R D که دوباره 3 مرحله ی اول مسیر سوم (R R D) چاپ نشده چون عینا توی مسیر دوم هست. الی آخر.
میشه با روشی کاری کرد که همه رو چاپ کنه (مثل آرایه) اما من خواستم ساده تر باشه تا موضوع رو بگیری بعد خودت کامل بنویسی
Last edited by m3hrz4d; 25-11-2007 at 07:50.
استاد ما هنوز تابع بازگشتی رو نگفته من خودم از کتاب جعفر نژاد قمی خوندم. خیلی سخته هر کاری می کنم نمی تونم بفهمم می تونی برام توضیح بدی؟ تو خودت چه جوری فهمیدی؟
استاد گفته بود که این تمرین اختیاریه و هر کی بیاره 1 نمره می گیره.
يك نكته راجع به تابع بازگشتي در نظر داشته باش كه چون توابع بازگشتي با پشته stack كار مي كند، به سرعت پشته را پر كرده و اگر تعداد مراجعه به آن بيش از حد معقول باشد باعث overflow پشته خواهد شد. برنامه نويسان حرفه اي بر خلاف تصور استفاده از توابع بازگشتي را مگر در مواقع ضروري پيشنهاد نمي كنند.(جهت استحضار)
اینو تقریبا فهمیدم. میشه با آرایه هم بگی شاید اونجوری راحتتر مسئله رو بگیرم
Last edited by amsjavan; 25-11-2007 at 10:29.
سلام من توي يك برنامه يك مشكل عجيب پيدا كردم.
اين قسمتي از برنامه ي منه:
for (i=99;i>=0;i--)
B[i]=getche()-48;
B[100]=0;
for (i=0;i<=200;i++)
C[i]=0;
كه تو اين برنامه توي آرايه ي B قراره صد تا عدد بريزه و اعداد آرايه C رو هم صفر كنه اما مشكل اين جاست كه B[0] رو وقتي مي گيره از دست مي ده يعني وقتي برنامه رو اين جوري اجرا مي كنم:
for (i=99;i>=0;i--)
B[i]=getche()-48;
B[100]=0;
printf("\n%d%d",B[1],B[0]);
for (i=0;i<=200;i++)
C[i]=0;
printf("\n%d%d",B[1],B[0]);
در پرينت اول بي صفر و يك رو درست چاپ مي كنه اما در دومين پرينت مقدار بي صفر رو از دست مي ده و به جاش عدد صفر رو چاپ مي كنه!
حالا مشكل اين از كجاست؟
اگر خطوط برنامه اتان دقيقا" همين هست كه نوشتيد، احتمالا" در بخشي از برنامه []B بصورت تابعي از []C تعريف شده است. بهمين دليل است كه با تغيير []Cمقادير[] B تغيير مي كند. بررسي كنيد واگر حل نشد و تمايل داشتيد برنامه را كامل بگذاريد تا شايد بتوان مشكل را حل كرد.
علاوه بر اين مشكل،شما كه از ورودي عدد ميگيريد ،چرا از تابع getche استفاده كرده ايد؟
معمولا وقتی بخواهیم یه عمل تکراری رو چندین بار انجام بدیم میتونیم از توابع بازگشتی استفاده کنیم و توی تابع, خود تابع رو صدا بزنیم و با استفاده از چک کردن آرگومان ها این حلقه تا یه جایی ادامه پیدا کنه.
فکر کنم یه مثال ساده در مورد توابع بازگشتی تابع فاکتوریل بشه (گرچه نوشتن فاکتوریل به صورت بازگشتی از لحاظ سرعت اجرا جالب نیست اما مثال خوبیه)
ما میخواهیم تابعی بنویسیم که این !5 رو حساب کنه.توی محاسبه ی این ضرب, ما عدد 1 رو داریم که در عدد بعدیش یعنی 2 ضرب میشه.نتیجه در عدد بعدی یعنی 3 ضرب میشه.بعدی در 4 و الی آخر.یعنی یه عمل تکراری باید انجام بشه.و البته برعکس هم میشه بهش نگاه کرد.ما عدد 5 رو داریم که باید در عدد کمتر از خودش یعنی 4ضرب بشه.نتیجه باید در عدد کمتر یعنی 3 ضرب بشه تا اینکه به 1 برسیم و وقتی به یک رسیدیم دیگه کار تمومه.کد:برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
تابع رو برای حالت دوم مینویسیم.
تابع(fact) فقط یک عدد(n) میگیره و فاکتوریلش رو برمیگردونه, به این صورت که اگه عدد یک بود, 1 رو برمیگردونه و در غیر این صورت, مقدار(n * fact(n-1 رو که برابر همون !n هست رو برمیگردونه.وقتی توی خود تابع, (fact(n-1 فراخوانی میشه, مسیر برنامه به اول تابع میره (مثل وقتی که توی یک تابع, یک تابع دیگه رو صدا بزنی) و n-1 رو به تابع میده.دوباره اینجا اگه n دو باشه n-1 میشه 1 و تابع 1 رو برای تابع فراخواننده(که همین تابع هست) برمیگردونه در نتیجه در تابع اول, (fact(n-1 رو برمیگردونه. اگه n بیشتر از 2 باشه دوباره توی تابع دوم تابع fact برای بار دوم صدا زده میشه (fact(n-1 -1 و مقدار در n-1 ضرب میشه و برای تابع اول فرستاده میشه.
این حلقه ی تو در تو تا جایی که n ی که برای تابع فرستاده میشه 1 نباشه ادامه پیدا میکنه و نتیجه ای که توی اولین تابع بدست میاد میشه :
میدونم شاید درست توضیح ندادم روی شکل خیلی راحتر میشه توضیح داد.اگه از یه IDE مثل Visual Studio که Debug قوی داشته باشه استفاده میکنی, با Trace کردن خط به خط این تابع خیلی راحتتر متوجه میشی که منظور چیه :کد:برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
کد:برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
Last edited by m3hrz4d; 26-11-2007 at 12:23.
با آرایه ساده تر نمیشه اما اینجا برای اینکه خیلی پیچیده نشه از آرایه ایستا(Static) استفاده کردم(فکر کنم هنوز آرایه پویا(استفاده از new) رو نخونده باشین) واسه همین طول آرایه باید از قبل مشخص باشه و برنامه نمیتونه برای هر M و N ی نتیجه رو حساب کنه.آرایه دو بعدی رو 20 در 6 گرفتم تا نتیجه ی مساله برای حالت 3 در 3 توش ریخته بشه(20 مسیر 6 حرکتی) و چاپ بشه.ضمن اینکه باز هم واسه سادگی آرایه رو سراسری تعریف کردم و آرایه به صورت آرگومان به تابع ارسال نمیشه.اگه میخوای برای مقدار های بیشتر هم نتیجه رو ببینی باید اندازه ی آرایه رو بیشتر کنی :
تابع آرایه رو پر میکنه و بعد توی main چاپ میشهکد:برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
[/SIZE]
هم اکنون 1 کاربر در حال مشاهده این تاپیک میباشد. (0 کاربر عضو شده و 1 مهمان)