Sunteți pe pagina 1din 6

Ministerul Educației, Culturii și Cercetării al Republicii Moldova

IPLT „Mihai Eminescu” din municipiul Bălți

Studiu comparativ

„Recursivitatea vs. Iterativitatea”

{
¿ n+1 , dacă m=0
A ( m , n )= ¿ A (m−1 , 1), dacă n=0 , m>0
¿ A (m−1 , A(m, n−1)), dacă m> 0 , n>0

Disciplină: Informatică
Elaborat de: SPĂTARU Mihail
elev al clasei a XII-a „D”
Profesor: CURBET Gheorghe
Grad didactic Superior

Bălți, 2023
În cadrul acestui studiu comparativ, ne propunem să analizăm diferențele semnificative între abordările iterativă
și recursivă în implementarea funcției Ackermann. Această funcție, notată convențional ca A(m, n), reprezintă un
teren propice pentru evaluarea avantajelor și dezavantajelor asociate acestor abordări, datorită naturii sale recursive
și creșterii rapide a complexității. În preambul, vom examina caracteristicile distinctive ale implementărilor
iterative și recursive, evidențiind avantajele și dezavantajele fiecăreia în contextul specific al funcției Ackermann.

Paradigme Programatice: Iterativitate vs. Recursivitate


Iterativitate Recursivitate
Necesarul de memorie Se manifestă printr-un consum de Caracterizată de un necesar de memorie
memorie moderat, cu utilizarea unui substanțial mai mare, ca rezultat al adăugării
vector pentru stocarea datelor repetate a cadrelor de stivă la fiecare apel
intermediare. recursiv.
Timpul de execuție Raportează timpuri de execuție Furnizează, de asemenea, timpuri de
comparabile cu varianta recursivă execuție asemănătoare cu varianta iterativă.
pentru specificul funcției Ackermann.
Structura programului Exhibă o structură complexă, dictată Adoptă o arhitectură mai simplă, conformă
de gestionarea explicită a stivei și cu definiția matematică a funcției
necesitatea construcției buclei Ackermann.
iterative.
Volumul de muncă Reclamă un efort semnificativ mai Induce un volum redus de muncă, reflectând
necesar pentru scrierea mare în procesul de dezvoltare și direct formularea matematică a problemei.
programului întreținere, având în vedere gestionarea
explicită a stivei și construcția buclei
iterative.
Testarea și depanarea Simplifică procesele de testare și Face acest proces mai complex, impunând o
programelor depanare, facilitând identificarea și atenție sporită asupra gestionării apelurilor
remedierea erorilor. recursive și a stării stivei.

Rezultate Experimentale:
- Valoarea Ackermann (4, 1): Identitate între cele două variante - 65533.
- Timpul de execuție Ack_It: 15.1338 sec.
- Timpul de execuție Ack_Rec: 18.9883 sec.

Varianta interativă:
Q27(n)=1 Q17(n)=3 Q8(n)=0+max(2,13)+1=14
Q25(n)=1 Q16(n)=2 Q7(n)=2
Q24(n)=1+1+1=3 Q15(n)= 2+3+2+2+2+1=12 Q6(n)=2
Q23(n)=1 Q14(n)=1 Q5(n)=19
Q22(n)=1+3+1=5 Q13(n)=3 Q4(n)=19m+m+1=20m+1
Q21(n)=1+5+1=7 Q12(n)=2 Q3(n)=2
Q20(n)=2 Q11(n)=2+3+1+1=7 Q2(n)=1
Q19(n)=2 Q10(n)=0+12+1=13 Q1(n)=20m+1+2+1+1=20m+5
Q18(n)=2 Q9(n)=2
Vd(n)=12B Vs(n)=12B V(n)=24B
Varianta recursivă:
Structura este prea complicată pentru estimarea manuală corectă.

Concluzii:
În cadrul acestui studiu comparativ privind utilizarea iterativității și recursivității în soluționarea problemei
funcției Ackermann, rezultatele evidențiază aspecte distinctive între cele două paradigme de programare.
Iterativitatea, prezentând un consum moderat de memorie și timpuri de execuție comparabile cu varianta recursivă,
presupune totuși o complexitate structurală considerabilă în implementare. Acest lucru derivă din necesitatea
gestionării stivei și construcției buclei iterative, elemente definitorii ale programelor iterative. În contrast,
recursivitatea aduce cu sine o eleganță conceptuală, în conformitate cu definiția matematică a funcției Ackermann,
însă la un cost semnificativ de memorie, manifestând o creștere exponențială. Această abordare complică procesul
de testare și depanare, deoarece necesită o atenție sporită în administrarea apelurilor recursive și a stării stivei.
Astfel, alegerea între aceste două paradigme depinde de un echilibru complex între eficiența utilizării resurselor și
claritatea conceptuală, și trebuie să țină cont de particularitățile problemei abordate și de preferințele individuale ale
fiecăruia.

Varianta iterativă Varianta recursivă


#include <iostream> #include <iostream>
#include <ctime> #include <ctime>

using namespace std; using namespace std;

const int dim = 100000; int Ack_Rec(int m, int n) {


long s[dim]; if (m == 0)
long d, m, n; return n + 1;
else if ((m > 0) && (n == 0))
long Ack_It(long m, long n) { return Ack_Rec(m - 1, 1);
long t; else if ((m > 0) && (n > 0))
t = 1; return Ack_Rec(m - 1, Ack_Rec(m, n - 1));
s[t] = m;
return 0;
do { }
m = s[t];
t = t - 1; int main() {
if (m == 0) clock_t T1, T2;
n = n + 1; int A;
else if (n == 0) {
t = t + 1; T1 = clock();
s[t] = m - 1; A = Ack_Rec(4, 1);
n = 1; T2 = clock();
} else {
t = t + 1; cout << "Valoarea: " << A << endl;
s[t] = m - 1; cout << "Timp de executie T1: " << (double)(T1) /
t = t + 1; CLOCKS_PER_SEC << " sec" << endl;
s[t] = m; cout << "Timp de executie T2: " << (double)(T2) /
n = n - 1; CLOCKS_PER_SEC << " sec" << endl;
}; cout << "Timp de executie T(n): " << (double)(T2 - T1) /
if (t > d) { CLOCKS_PER_SEC << " sec" << endl;
d = t;
if (d >= dim) return 0;
cout << "Eroare! "; }
}
} while (t != 0);

return n;
}

int main() {
clock_t T1, T2;
long A;

T1 = clock();
A = Ack_It(4, 1);
T2 = clock();

cout << "Valoarea: " << A << endl;


cout << "Timp de executie T1: " << (double)(T1) /
CLOCKS_PER_SEC << " sec" << endl;
cout << "Timp de executie T2: " << (double)(T2) /
CLOCKS_PER_SEC << " sec" << endl;
cout << "Timp de executie T(n): " << (double)(T2 - T1) /
CLOCKS_PER_SEC << " sec" << endl;

return 0;
}
Valoarea: 65533 pentru Ack_It(4, 1) Valoarea: 65533 pentru Ack_Rec(4, 1)
Timp de executie T1: 0.001911 sec Timp de executie T1: 0.001473 sec
Timp de executie T2: 15.1357 sec Timp de executie T2: 18.9897 sec
Timp de executie T(n): 15.1338 sec Timp de executie T(n): 18.9883 sec

Sarcini de lucru – programare:


√ √
a) Suma rădăcinilor pătrate: S= 1+ 2+ √ 3+ √ 4 +... √ n

Suma Rădăcinilor Pătrate - Recursivă


1 #include <iostream>
2 #include <cmath>
3
4 using namespace std;
5
6 double suma_radacinilor_patrate_rec(int n) {
7 if (n == 1) {
8 return sqrt(1.0);
9 } else {
1 return sqrt(n + suma_radacinilor_patrate_rec(n - 1));
0 }
1 }
1
1 int main() {
2 int n;
1
3 cout << "Introdu valoarea pentru Suma Rădăcinilor Pătrate (Recursivă): ";
1 cin >> n;
4
1 double rezultat = suma_radacinilor_patrate_rec(n);
5
1 cout << "Suma rădăcinilor pătrate pentru n=" << n << " este: " << rezultat << endl;
6
1 return 0;
7 }
1
8
1
9
2
0
2
1
2
2
2
3
2
4
2
5

Suma Rădăcinilor Pătrate - Iterativă


1 #include <iostream>
2 #include <cmath>
3
4 using namespace std;
5
6 double suma_radacinilor_patrate_it(int n) {
7 double rezultat = 0.0;
8 for (int i = n; i >= 1; --i) {
9 rezultat = sqrt(i + rezultat);
1 }
0 return rezultat;
1 }
1
1 int main() {
2 int n;
1
3 cout << "Introdu valoarea pentru Suma Rădăcinilor Pătrate (Iterativă): ";
1 cin >> n;
4
1 double rezultat = suma_radacinilor_patrate_it(n);
5
1 cout << "Suma rădăcinilor pătrate pentru n=" << n << " este: " << rezultat << endl;
6
1 return 0;
7 }
1
8
1
9
2
0
2
1
2
2
2
3
2
4
2
5

b) Suma alternantă: S=2−4 +6−8+10−12+ ...+ ¿

Suma Alternantă - Recursivă


3 #include <iostream>
4 #include <cmath>
5
6 using namespace std;
7
8 int suma_alternanta_rec(int n) {
9 if (n == 1) {
1 return 2;
0 } else {
1 return pow(-1, n + 1) (2 n) + suma_alternanta_rec(n - 1);
1 }
1 }
2
1 int main() {
3 int n;
1
4 cout << "Introdu valoarea pentru Suma Alternantă (Recursivă): ";
1 cin >> n;
5
1 int rezultat = suma_alternanta_rec(n);
6
1 cout << "Suma alternanta pentru n=" << n << " este: " << rezultat << endl;
7
1 return 0;
8 }
1
9
2
0
2
1
2
2
2
3
2
4
2
5

Suma Alternantă - Iterativă


1 #include <iostream>
2 #include <cmath>
3
4 using namespace std;
5
6 int suma_alternanta_it(int n) {
7 int rezultat = 2;
8 for (int i = 2; i <= n; ++i) {
9 rezultat += pow(-1, i + 1) (2 i);
1 }
0 return rezultat;
1 }
1
1 int main() {
2 int n;
1
3 cout << "Introdu valoarea pentru Suma Alternantă (Iterativă): ";
1 cin >> n;
4
1 int rezultat = suma_alternanta_it(n);
5
1 cout << "Suma alternanta pentru n=" << n << " este: " << rezultat << endl;
6
1 return 0;
7 }
1
8
1
9
2
0
2
1
2
2
2
3
2
4
2
5

S-ar putea să vă placă și