Theory
જે function પોતાને ફોન કરે છે
અત્યાર સુધી દરેક function એ બીજાઓને call કર્યા. C કંઈક વિચિત્ર ને પરવાનગી આપે છે: એક function પોતાને call કરતું.
પહેલી પ્રતિક્રિયા, બરાબર જ: "એ તો હંમેશા loop કરતું રહેશે."
લગભગ. એક ગુમ ઘટક સાથે એ ખરેખર અરીસાઓનો અનંત hall છે, અને એ ઘટક સાથે એ આ subject ની સૌથી સુંદર ચાર lines બની જાય છે: factorial, એવા function થી compute થતું જે મોટા ભાગનું કામ પોતાની જ એક નાની copy પર ભરોસો કરીને કરાવે છે.
Theory
કતારમાં આગળ પૂછવું
તમે એક લાંબી કતારમાં છેલ્લા છો અને તમારી position જાણવી છે. આગળના ને પૂછો: "તમારી position શું છે?" એમને પણ ખબર નથી, એટલે એ આગળ પૂછે છે... જ્યાં સુધી સવાલ પહેલા વ્યક્તિ સુધી પહોંચે, જે બસ જાણે છે: "હું number 1 છું" (base case). હવે જવાબ પાછળની તરફ વહે છે, દરેક વ્યક્તિ એક ઉમેરે છે, જ્યાં સુધી તમારો જવાબ આવી જાય. એક સવાલ નીચે મોકલ્યો, જવાબ ઉપર બનતા ગયા: આ જ recursion ની આખી machinery છે.
Theory
Recursion, ઔપચારિક રીતે
એક recursive function ને બરાબર બે ભાગ જોઈએ:
- Base case: સૌથી નાનું input, સીધો જવાબ અપાય, કોઈ આગળ call નહીં. આ જ brake છે.
- Recursive case: problem ને એક નાના self દ્વારા ફરી કહેવાય.
Factorial (n! = n × (n-1) × ... × 1) સ્વાભાવિક રીતે ફરી કહેવાય છે: n! = n × (n-1)! અને 0! = 1:
int factorial(int n) {
if (n == 0) return 1; /* base case */
return n * factorial(n - 1); /* smaller self */
}
દરેક call એ base case ની તરફ વધવું જોઈએ, દર વખતે નાનું n, નહીંતર brake ક્યારેય પહોંચતું નથી.
Practical
Factorial, recursive અને loop વાળું
#include <stdio.h>
int factorial(int n) {
if (n == 0) return 1;
return n * factorial(n - 1);
}
int main() {
int f = 1, i, n = 4;
printf("Recursive: %d\n", factorial(4));
for (i = 1; i <= n; i++) f = f * i; /* the loop twin */
printf("Loop : %d\n", f);
return 0;
}This example runs in Gri-Learn on the web, where you can edit it and see the output.
Think first
Stack ને trace કરો
factorial(4) ને કાગળ પર trace કરો: calls ની શૃંખલા નીચે જતી લખો, ચિહ્નિત કરો ક્યાં થોભે છે, પછી પાછા ઉપર આવતા પરિણામોને ગુણો. શું return થાય છે, અને કયા data structure એ થોભેલી calls ને પકડી?
Show the answer
નીચે: f(4) → f(3) → f(2) → f(1) → f(0), પાંચ calls, દરેક થોભીને રાહ જુએ છે. f(0) base case પર પહોંચે છે: 1. ઉપર: 1×1=1, 2×1=2, 3×2=6, 4×6=24.
થોભેલી calls call stack પર રાહ જોતી રહી, last in, first out, બરાબર એ જ LIFO structure જે BCA304 ના મુખ્ય lesson નું છે. દરેક recursion વેશ બદલીને કામ કરતું stack છે.
Quiz
એક student base case ભૂંસી નાખે છે: int factorial(int n) { return n * factorial(n - 1); } અને factorial(4) call કરે છે. શું થાય છે?
- Calls ક્યારેય થોભતી નથી; call stack overflow થાય છે અને program crash થઈ જાય છે
- તોય 24 return કરે છે, C ને factorials ખબર છે
- એક compile error: base cases ફરજિયાત syntax છે
- તરત 0 return કરે છે
Show the answer
Calls ક્યારેય થોભતી નથી; call stack overflow થાય છે અને program crash થઈ જાય છે
brake વગર, f(4), f(3) ને call કરે છે... f(0), f(-1), f(-2), હંમેશા નાનું, ક્યારેય ન થોભતું. દરેક થોભેલી call stack memory રોકે છે જ્યાં સુધી એ ખૂટી ન જાય: stack overflow, એક runtime crash (કોઈ compile error નહીં, syntax legal છે). "base case વગર શું થાય છે" એ અસ્તિત્વમાં recursion નો સૌથી પાક્કો સવાલ છે.
Quiz
Factorial, loop તરીકે અને recursion તરીકે, બંને રીતે કામ કરે છે. કયું statement એમની સાચી સરખામણી કરે છે?
- બંને સાચાં છે; loop stacked calls થી બચે છે, recursion સ્વાભાવિક રીતે nested problems પર ચમકે છે
- Recursion હંમેશા loops થી ઝડપી છે
- Loops 3 થી ઉપર factorials compute કરી શકતા નથી
- Recursion ક્યારેય વધારાની memory વાપરતું નથી
Show the answer
બંને સાચાં છે; loop stacked calls થી બચે છે, recursion સ્વાભાવિક રીતે nested problems પર ચમકે છે
Factorial જેવી સીધી ગણતરી માટે, loop એટલો જ સાફ અને સસ્તો છે (થોભેલી calls નો ઢગલો નહીં). Recursion ત્યાં પોતાની કમાણી કરે છે જ્યાં problem પોતે nested હોય, folders ની અંદર folders, Tower of Hanoi, આગળ BCA304 માં tree structures, જ્યાં loop વાળું version કદરૂપું થઈ જાય છે. Tool, problem ના આકાર ને અનુસરે છે: આ જ exam લાયક સરખામણી છે.
Watch out
Marks ક્યાં કપાય છે
કોઈ base case નહીં, કે એવો જ્યાં calls ક્યારેય પહોંચતી નથી (factorial(n-1) સાથે n == 5 વાળો base, 4 પર call): બંને stack overflow માં પૂરા થાય છે, નાનું થવાની દિશા તપાસો. ખોટી base value: factorial(0) એ 1 return કરવું જોઈએ, 0 નહીં, એક ખોટો brake અને એની ઉપરનો દરેક જવાબ 0. બેદરકારીથી trace કરવું: exams નીચે-શૃંખલા અને ઉપર-ગુણાકાર બંને લખેલા માંગે છે; પાછા ફરવાની સફર છોડવાથી અડધા marks જાય છે.
Theory
ક્લાસિક બીજું ઉદાહરણ
Fibonacci (દરેક number એ પાછલા બે નો સરવાળો: 0 1 1 2 3 5 8...) એ recursion નો બીજો exam સિતારો છે: fib(n) = fib(n-1) + fib(n-2), બે base cases સાથે (fib(0)=0, fib(1)=1). આજે રાત્રે એને લખો; fib(4) trace કરો. C માં એક lesson બાકી છે: struct, જ્યાં આપણા student ને આખરે name, marks અને grade એક જ record માં મળે છે, આખા subject નું ઇનામ.
Summary
Key takeaways
- Recursion: એક function જે પોતાને નાના input પર call કરે છે.
- બે ફરજિયાત ભાગ: base case (brake) + recursive case (નાનું self).
- factorial: if (n == 0) return 1; return n * factorial(n - 1);
- થોભેલી calls call stack પર રાહ જુએ છે (LIFO); પરિણામ પાછા ફરતાં ગુણાય છે.
- કોઈ base case નહીં → stack overflow crash; base પહોંચવા લાયક અને સાચો હોવો જોઈએ.
- સીધી ગણતરી માટે loops; સ્વાભાવિક રીતે nested problems માટે recursion.
- યાદ રાખવાની યુક્તિ: કતારમાં આગળ પૂછો, જવાબ પાછા ઉપર આવે છે.