مشخصات مقاله
-
3352
-
0.0
-
17918
-
0
-
0
توابع بازگشتی در سی شارپ (recursive function)
وقتی توی برنامهنویسی C# با مسئلهای روبهرو میشید که حلش به تکرار یک الگوی مشخص نیاز داره، گاهی میتونید از متدهای بازگشتی کمک بگیرید. در این روش، یک متد میتونه خودش رو دوباره فراخوانی کنه و مسئله رو مرحلهبهمرحله جلو ببره.
توی این آموزش میخوایم با مفهوم تابع بازگشتی در سی شارپ آشنا بشیم و با چند مثال ببینیم چطور میشه متدهای بازگشتی رو ایجاد و استفاده کرد. اگر در مسیر یادگیری C# هستید، درک درست این مفهوم باعث میشه کار کردن با این نوع متدها براتون خیلی راحتتر بشه.
در این بخش میخوایم سراغ تابع بازگشتی در سی شارپ بریم. به طور کلی، توابع بازگشتی در تعریف ریاضی به عملیاتی گفته میشن که خروجی هر مقدار، بر اساس اجرای یک فرمول مشخص روی مقادیر قبلی به دست میاد. مثلاً فاکتوریل هر عدد برابر با حاصلضرب اون عدد در فاکتوریل عددی یک واحد کوچکتره. در تقریباً همه زبانهای برنامهنویسی، از جمله سی شارپ، از روشهای بازگشتی برای حل بعضی مسائل رایج و کاربردی استفاده میشه.
فرض کنید میخواید اعداد فرد مثبت رو از یک مقدار مشخص به سمت یک مقدار کمتر بشمارید. مثلاً برای شمردن اعداد فرد از 1 تا 9، به این شکل پیش میریم:
9, 7, 5, 3, 1
برای انجام این کار، اول بالاترین مقدار رو در نظر میگیریم و بعد 2 واحد از اون کم میکنیم تا به مقدار قبلی برسیم. در برنامهنویسی هم برای حل این مسئله، ابتدا متد رو مینویسیم و بعد کاری میکنیم که متد دوباره خودش رو فراخوانی کنه. این دقیقاً همون چیزی هست که پایهی بازگشت در برنامهنویسی رو تشکیل میده.
- برای ایجاد یک برنامهی کاربردی جدید، از منوی اصلی روی File -> New Project... کلیک کنید.
- از لیست وسط، گزینهی Empty Project رو انتخاب کنید.
- اسم پروژه رو به Recursions تغییر بدید و کلید Enter رو بزنید.
- در پنجرهی Solution Explorer راستکلیک کنید و بعد گزینههای Recursions -> Add -> New Item رو انتخاب کنید.
- از لیست وسط روی Code File کلیک کنید.
- اسم فایل رو Calculator بذارید و کلید Enter رو فشار بدید.
ایجاد متد بازگشتی
یکی از الگوهای کلی برای ایجاد یک متد بازگشتی به شکل زیره:
ReturnValue Function(Arguments, if any)
{
Optional Action...
Function();
Optionan Action...
}
یک متد بازگشتی با یک مقدار بازگشتی شروع میشه. اگر متد قرار نباشه مقداری برگردونه، میتونید اون رو با کلمهی کلیدی void تعریف کنید. بعد از نام متد هم میشه یک یا چند آرگومان برای اون در نظر گرفت. در بیشتر مواقع، متد بازگشتی حداقل یک آرگومان دریافت میکنه و در هر مرحله مقدار اون رو تغییر میده. داخل بدنهی متد هم میتونید هر کاری که لازم دارید انجام بدید. در پیادهسازی متدهای بازگشتی، دو نکتهی اصلی وجود داره که حتماً باید رعایت بشن.
اول اینکه متد باید در داخل بدنهی خودش دوباره فراخوانی بشه. دوم اینکه قبل یا بعد از این فراخوانی، باید شرطی داشته باشیم که مشخص کنه چه زمانی متد باید متوقف بشه. اگر چنین شرطی وجود نداشته باشه، متد به اجرای خودش ادامه میده و هیچوقت متوقف نمیشه. برای مثال بالا، میتونیم متدی ایجاد کنیم که یک عدد صحیح (integer) به عنوان آرگومان دریافت کنه. برای اینکه موضوع سادهتر باشه، فقط اعداد مثبت رو در نظر میگیریم. داخل بدنهی متد، مقدار فعلی آرگومان رو نمایش میدیم، بعد 2 واحد از اون کم میکنیم و در نهایت خود متد رو دوباره فراخوانی میکنیم.
using System;
public class Exercise
{
static void OddNumbers(int a)
{
if (a >= 1)
{
Console.Write("{0}، "، a);
a -= 2;
OddNumbers(a);
}
}
public static int Main()
{
const int number = 9;
Console.WriteLine("Odd Numbers");
OddNumbers(number);
Console.WriteLine();
return 0;
}
}
همونطور که میبینید، متد داخل بدنهی خودش دوباره فراخوانی میشه. نتیجهی اجرای برنامه هم به صورت زیر خواهد بود:
Odd Numbers 9, 7, 5, 3, 1, Press any key to continue...
طراحی به صورت بازگشتی
- برای ایجاد تابع بازگشتی، ابتدا فایل رو به شکل زیر تغییر بدید.
using System;
public class Calculator
{
private long Factorial(long number)
{
if (number <= 1)
return 1;
return number * Factorial(number - 1);
}
public static int Main()
{
long factor = 0;
Calculator exo = new Calculator();
Console.Write("To calculate a factorial, enter a (small positive) number: ");
factor = long.Parse(Console.ReadLine());
Console.WriteLine("The factorial of {0} = {1}",
factor, exo.Factorial(factor));
System.Console.ReadKey();
return 0;
}
}
- برنامه رو اجرا و تست کنید.
- عدد 8 رو وارد کنید و Enter رو بزنید.
To calculate a factorial، enter a (small positive) number: 8 The factorial of 8 = 40320 Press any key to continue...
- با زدن کلید Enter از پنجرهی DOS خارج بشید.
استفاده از متدهای بازگشتی
متدهای بازگشتی برای ساختن سریها و لیستهایی که از یک الگوی مشخص پیروی میکنن، کاربرد زیادی دارن. این مقادیر میتونن به صورت افزایشی یا کاهشی محاسبه بشن. حالا فرض کنید به جای اینکه فقط اعداد فرد رو نمایش بدیم، مثل مثال قبلی، بخوایم اونها رو به صورت تصاعدی با هم جمع کنیم. اگر فقط عدد 1 رو داشته باشیم، نتیجه 1 میشه. اگر عدد 5 رو داشته باشیم، 1 رو با 3 جمع میکنیم و بعد نتیجهی بهدستاومده رو با 5 جمع میکنیم و همین روند رو ادامه میدیم. این فرایند رو میشه به شکل زیر نمایش داد.
برای انجام این محاسبه، اول از عدد 1 شروع میکنیم. اگر عدد برابر 1 یا کوچکتر از اون باشه، متد مقدار 1 رو برمیگردونه. در غیر این صورت، 2 واحد رو به مقدار قبلی اضافه میکنیم و بعد این روند رو روی نتیجهی بهدستاومده ادامه میدیم. این کار تا زمانی که به مقدار آرگومان برسیم ادامه پیدا میکنه. متد رو میتونیم به شکل زیر ایجاد یا پیادهسازی کنیم.
using System;
public class Exercise
{
static int AdditionalOdd(int a)
{
if (a <= 1)
return 1;
return a + AdditionalOdd(a - 2);
}
static void OddNumbers(int a)
{
if (a >= 1)
{
Console.Write("{0}, ", a);
a -= 2;
OddNumbers(a);
}
}
public static int Main()
{
const int Number = 9;
Console.WriteLine("Odd Numbers");
Console.WriteLine();
Console.WriteLine("Sum of Odds: {0}\n", AdditionalOdd(Number));
return 0;
}
}
نتیجهی اجرای برنامه به شکل زیر خواهد بود:
Odd Numbers 9, 7, 5, 3, 1, Sum of Odds: 25 Press any key to continue...
بهکاربردن متدهای بازگشتی
- فایل رو به شکل زیر تغییر بدید.
using System;
public class Calculator
{
private long Factorial(long number)
{
if (number <= 1)
return 1;
return number * Factorial(number - 1);
}
private long Permutation(long n, long r)
{
if (r == 0)
return 0;
if (n == 0)
return 0;
if ((r >= 0) && (r <= n))
return Factorial(n) / Factorial(n - r);
else
return 0;
}
private long Combinatorial(long a, long b)
{
if (a <= 1)
return 1;
return Factorial(a) / ( ( Factorial(b) * Factorial(a - b) ) );
}
public static int Main()
{
long factor = 0;
long second = 0;
Calculator exo = new Calculator();
Console.Write("To calculate a factorial, enter a (small positive) number: ");
factor = long.Parse(Console.ReadLine());
Console.Write("To calculate a permutation and the combination, enter a second (small positive) number: ");
second = long.Parse(Console.ReadLine());
Console.WriteLine("Factorial: F({0}) = {1}",
factor, exo.Factorial(factor));
Console.WriteLine("Permutation: P({0}, {1}) = {2}",
factor, second, exo.Permutation(factor, second));
Console.WriteLine("Combination: C({0}, {1}) = {2}",
factor, second, exo.Combinatorial(factor, second));
System.Console.ReadKey();
return 0;
}
}
- برنامه رو تست کنید.
- به عنوان اولین عدد درخواستی، 20 رو وارد کنید و بعد Enter رو بزنید.
- برای عدد دوم، 5 رو وارد کنید و کلید Enter رو فشار بدید.
To calculate a factorial, enter a (small positive) number: 20 To calculate a permutation and the combination, enter a second (small positive) number: 5 Factorial: F(20) = 2432902008176640000 Permutation: P(20, 5) = 1860480 Combination: C(20, 5) = 15504
اگه میخواید یادگیری C# رو منسجمتر ادامه بدید، قدم بعدی میتونه این باشه که با مفاهیم و ساختارهای مهم این زبان عمیقتر آشنا بشید. برای ادامهی مسیر و تمرین مباحث مختلف برنامهنویسی با C# میتونید از دوره آموزش C# استفاده کنید و مطالب رو به شکل اصولی و کاربردی پیش ببرید.