Recursive Functions (পুনরাবৃত্তি ফাংশন) হল এমন ফাংশন যা নিজেকে কল করে। এটি সমস্যার সমাধানকে ছোট ছোট সাব-সমস্যায় বিভক্ত করে এবং এগুলি একে একে সমাধান করে। সাধারণত পুনরাবৃত্তি ব্যবহৃত হয় এমন সমস্যাগুলিতে যেখানে সমস্যাটি আরও ছোট আকারে একই ধরণের সমস্যায় বিভক্ত করা যায়।
এখানে, আমরা Recursion এবং Recursive Function এর ব্যবহার দেখব, কিছু সমস্যা সমাধানের উদাহরণ সহ।
Recursion এর মৌলিক কাঠামো
একটি রিকর্সিভ ফাংশনের সাধারণ কাঠামো হলো:
- Base Case: এটি হলো ফাংশনটির সেরা বা শেষ অবস্থা, যেখানে পুনরাবৃত্তি থামবে। যদি base case না থাকে, তবে রিকর্সন অবিরাম চলে যাবে।
- Recursive Case: এখানে ফাংশনটি নিজেকে কল করে, সাধারণত সমস্যাটি আরও ছোট আকারে সমাধান করা হয়।
প্যাসক্যালের একটি রিকর্সিভ ফাংশনের উদাহরণ
ফ্যাক্টোরিয়াল (Factorial) হিসাব করা
ফ্যাক্টোরিয়াল হল এমন একটি সংখ্যা যা ১ থেকে ঐ সংখ্যাটি পর্যন্ত সব সংখ্যার গুণফল। উদাহরণস্বরূপ, 5 এর ফ্যাক্টোরিয়াল হলো:
5! = 5 × 4 × 3 × 2 × 1 = 120এই সমস্যাটি রিকর্সিভভাবে সমাধান করা যায়:
- Base case:
n = 0হলে, ফ্যাক্টোরিয়াল হবে 1। - Recursive case:
n! = n × (n-1)!
ফ্যাক্টোরিয়াল ফাংশন প্যাসক্যালের মাধ্যমে
program FactorialExample;
function Factorial(n: Integer): Integer;
begin
if n = 0 then
Factorial := 1 { Base case: 0! = 1 }
else
Factorial := n * Factorial(n - 1); { Recursive case: n! = n * (n-1)! }
end;
var
number: Integer;
begin
writeln('Enter a number: ');
readln(number);
writeln('Factorial of ', number, ' is: ', Factorial(number));
end.এখানে, Factorial ফাংশনটি নিজেকে কল করে এবং ধীরে ধীরে n এর মান কমায় যতক্ষণ না n = 0 হয়ে যায়। এটি তখন 1 রিটার্ন করে, এবং তারপরে রিকর্সিভভাবে ফ্যাক্টোরিয়াল হিসাব করা হয়।
ফিবোনাচ্চি সিরিজ (Fibonacci Sequence)
ফিবোনাচ্চি সিরিজে পরবর্তী সংখ্যা হলো পূর্ববর্তী দুটি সংখ্যার যোগফল। প্রথম দুটি সংখ্যা হলো 0 এবং 1, তারপর পরবর্তী সংখ্যা হবে 0 + 1 = 1, তারপর 1 + 1 = 2, তারপর 1 + 2 = 3, ইত্যাদি।
এটি রিকর্সিভভাবে হিসাব করা যায়:
- Base case:
Fib(0) = 0,Fib(1) = 1 - Recursive case:
Fib(n) = Fib(n-1) + Fib(n-2)
ফিবোনাচ্চি ফাংশন প্যাসক্যালের মাধ্যমে
program FibonacciExample;
function Fibonacci(n: Integer): Integer;
begin
if n = 0 then
Fibonacci := 0 { Base case: Fib(0) = 0 }
else if n = 1 then
Fibonacci := 1 { Base case: Fib(1) = 1 }
else
Fibonacci := Fibonacci(n - 1) + Fibonacci(n - 2); { Recursive case }
end;
var
number: Integer;
begin
writeln('Enter a number: ');
readln(number);
writeln('Fibonacci of ', number, ' is: ', Fibonacci(number));
end.এই ফাংশনটি Fibonacci ফাংশনটিকে রিকর্সিভভাবে কল করে এবং Fibonacci সিরিজের মান বের করে।
রিকর্সিভ ফাংশন এবং সমস্যা সমাধান
রিকর্সিভ ফাংশন সাধারণত এমন সমস্যাগুলির সমাধানে ব্যবহৃত হয় যেখানে:
- সমস্যা ছোট ছোট সাব-সমস্যায় বিভক্ত হতে পারে।
- সমস্যার সমাধান একটি সাধারণ রুল বা সূত্র দিয়ে করা যায় (যেমন ফ্যাক্টোরিয়াল, Fibonacci, গাছ বা গ্রাফ ট্রাভার্সাল)।
এগুলো কিছু উদাহরণ যেখানে রিকর্সিভ সমাধান প্রযোজ্য হতে পারে:
- হ্যানি-কম্বিনেটরি সমস্যা (Recursion in combinatorial problems): যেমন পাসক্যাল ট্রায়াঙ্গল (Pascal's Triangle), রূপান্তর (permutation), বা সমন্বয় (combination) গণনা করা।
- বিনারি গাছ বা ট্রি ট্রাভার্সাল (Binary tree or tree traversal): গাছের সব নোডের উপর পুনরাবৃত্তি করা।
- ডিভাইড অ্যান্ড কনকার (Divide and Conquer): যেমন Merge Sort বা Quick Sort অ্যালগরিদমগুলি রিকর্সিভ পদ্ধতিতে কাজ করে।
সীমাবদ্ধতা ও কার্যকারিতা
- স্ট্যাক ওভারফ্লো: যেহেতু রিকর্সন অনেক বার ফাংশন কল করতে পারে, তাই এটি স্ট্যাক ওভারফ্লো ঘটাতে পারে যদি প্রোগ্রামের গভীরতা খুব বেশি হয়।
- কার্যকারিতা: কিছু ক্ষেত্রে রিকর্সিভ সমাধান ইটারেটিভ সমাধানের তুলনায় কম কার্যকরী হতে পারে, কারণ অনেক সময় রিকর্সিভ ফাংশনগুলো পুনরায় একই গণনা করে (যেমন ফিবোনাচ্চি)। এ ধরনের সমস্যা এড়ানোর জন্য মেমোইজেশন (memoization) বা ডাইনামিক প্রোগ্রামিং ব্যবহার করা যেতে পারে।
সারাংশ
রিকর্সন একটি শক্তিশালী টুল যা প্রোগ্রামিংয়ে সমস্যাগুলির সমাধানকে ছোট ছোট অংশে বিভক্ত করে। রিকর্সিভ ফাংশনগুলি সাধারণত সোজা ও সংক্ষিপ্ত কোড লিখতে সাহায্য করে, তবে এগুলোর সীমাবদ্ধতা যেমন স্ট্যাক ওভারফ্লো এবং কার্যকারিতা নিয়ে চিন্তা করা প্রয়োজন। ফ্যাক্টোরিয়াল এবং ফিবোনাচ্চি সিরিজের মত উদাহরণগুলিতে রিকর্সন ব্যবহার করা অত্যন্ত সহজ এবং কার্যকর।
Read more