PDA

View Full Version : سوال: لطفا اصول تعریف یک تابع بازگشتی رو توضیح بدید



idocsidocs
پنج شنبه 19 مرداد 1391, 17:05 عصر
می خوام یه تابع بازگشتی (تابعی که خودش رو فراخوانی می کنه) ایجاد کنم.

اما نمی دونم باید چطور این کار رو انجام داد.

البته تعریف تابع رو که می دونم ولی نمی دونم موقع تعریف تابع بازگشتی باید به چه نکاتی توجه کرد. چون این تابع ممکنه خودش رو بینهایت بار فراخوانی کنه یا ... و کلا باید ریزه کاریهای چنین تابعی رو دونست.

لطفا در این مورد توضیح بدید.

MMSHFE
پنج شنبه 19 مرداد 1391, 17:21 عصر
در تعریف توابع بازگشتی توجه به چند نکته خیلی مهمه:
1- راهی بجز استفاده از تابع بازگشتی وجود نداشته باشه یا اگه باشه، استفاده از تابع بازگشتی بهینه تر باشه.
2- بطور کلی توابع بازگشتی کندتر از توابع غیربازگشتی هستن چون باید وضعیت تابع قبلی حفظ بشه و عمل Task Switching برای تابع جدید انجام بشه و درنتیجه، سرعت کاهش پیدا میکنه و مصرف حافظه بالا میره. پس باید با احتیاط این توابع رو بکار ببریم.
3- باید فراخوانی تابع توسط خودش مشروط به شرطی باشه که مطمئن باشیم در جایی، این فراخوانی متوقف میشه وگرنه برنامه دچار بن بست میشه. البته زبانهایی مثل PHP با قراردادن فراخوانیهای توابع درون پشته (Stack) و محدودکردن این فراخوانیها به تعداد مشخص (پیشفرض 200 عدد)، جلوی بن بست رو میگیرن. پس باید حواستون باشه که تابع شما بیش از 200 فراخوانی تودرتو نداشته باشه.
4- از توابع بازگشتی معمولاً وقتی استفاده میکنیم که تعداد دفعات تکرار مشخص نیست و ضمناً تابع نیاز به صدا زدن خودش داشته باشه و بعبارت دیگه، به خروجی فراخوانی خودش احتیاج داشته باشه. مثلاً محاسبه A به توان B رو میشه به دو روش بازگشتی و غیر بازگشتی نوشت:


<?php
function a_power_b($a, $b) {
$result = 1;
for($i = 0; $i < $b; $i++) {
$result *= $a;
}
return $result;
}

function a_pow_b($a, $b) {
return ($b == 1 ? $a : $a * a_pow_b($a, $b - 1));
}

$start = microtime(true);
echo '<p>' . a_power_b(5, 50);
$end = microtime(true);
echo ' ' . ($end - $start) . '</p>' . PHP_EOL;
$start = microtime(true);
echo '<p>' . a_pow_b(5, 50);
$end = microtime(true);
echo ' ' . ($end - $start) . '</p>' . PHP_EOL;
?>

نمونه خروجی:


8.8817841970013E+34 4.3153762817383E-5
8.8817841970013E+34 9.2983245849609E-5

همونطور که میبینید، تابع بازگشتی تقریباً 2 برابر غیربازگشتی زمان مصرف کرده. تازه مصرف حافظه بماند. این نشون میده که در استفاده از توابع بازگشتی باید با دقت و وسواس خیلی زیادی کار کرد و صرفاً استفاده از اونها رو به وضعیتهایی که چاره دیگری نداریم محدود کنیم.
موفق باشید.