CENTRUL DE PREGĂTIRE PENTRU PERFORMANȚĂ HAI LA OLIMPIADĂ ! DISCIPLINA INFORMATICĂ JUDEȚUL SUCEAVA Titlul lecției: Recursivitate. Data: 18.03.2017 Profesor: Petrică Galan Grupa a IX-a Seniori, locul de desfășurare: Colegiul Național „Ștefan cel Mare”, Suceava
Cuprins I. Recursivita Recursivitate te .................................................................. ................................................................................................... .................................................................... ..................................... .. 2 Prezentare Prezentare .............................................................. ................................................................................................. ...................................................................... ..................................... .. 2
Cum gândim un algoritm recursiv? ................................................................... .................................................................................................. ............................... 2 II. Exemple Exemple de utilizare utilizare ..................................................... ...................................................................................... ................................................................... ...................................... .... 3 1.
Algoritmi Algoritmi elementar elementarii .................................................................... ..................................................................................................... ............................................... .............. 3
2.
Prelucrarea Prelucrarea tablourilor tablourilor de memorie................. memorie.................................................. ................................................................... ........................................... ......... 3
3.
Recursivitatea în cascadă. .................................................................................. ............................................................................................................ .......................... 4
III. Aplicații propuse .............................................................. .................................................................................................. .................................................................. .............................. 4
Pagină | 1
I. Recursivitate Prezentare
Recursivitatea este o tehnică generală de elaborare a algoritmilor . Implementarea recursivității se face cu ajutorul funcțiilor care se auto -apelează. O funcție recursivă este o funcție care se apelează pe sine însăși pentru a efectua o anumită operație . Procesul prin care o funcție se apelează pe sine se numește recursivitate . Recursivitatea a venit din nevoia transcrierii formulelor recursive matematice.
Ex: Factorialul unui număr natural: Definiția matematică recursivă:
{ ( )
3!=3*2!=3*2*1!=3*2*1*0!=3*2*1*1=6
//iterativ long fact(unsigned n) { long factorial=1; for(unsigned i=1;i<=n;i++) factorial*=i; return factorial; } //recursiv long fact(unsigned n) { if(n==0) return 1; else return n*fact(n-1); }
Auto-apelul poate fi direct (în definiția funcției) sau indirect (printr -o altă funcție: o funcție A
apelează o funcție B care la rândul său apelează funcția A ). Funcțiile recursive sunt în general mai lente decât variantele lor iterative. Motivul este că la fiecare apel recursiv se introduce în program o suprasarcină de apel (se depun în stivă adresa de revenire și valorile parametrilor corespunzătoare apelului curent) . Pentru orice algoritm recursiv există unul iterativ ca re rezolvă aceeași problemă. Varianta recursivă este mai elegantă, mai scurtă dar mai lentă (recursivitatea este eficientă numai dacă numărul de autoapelări nu este prea mare pentru a nu se ajunge la umplerea zonei de memorie alocată). Cum gândim un algoritm recursiv? Exemplu: O cameră de luat vederi are în obiectiv un televizor care transmite imaginile primite de la cameră. În televizor se vede un televizor în care se vede un televizor… (ce se întâmplă la un nivel, se întâmplă la fiecare nivel). Deoarece recursivitatea este un proces repetitiv, este obligatorie existența unei condiții de oprire a
repetiției. În general aceasta este legată de valorile parametrilor sau ale unor variabile locale. Pe de altă parte, la fiecare apel recursiv se reduce dimensiun ea problemei, prin modificarea parametrilor și/sau a variabilelor locale, iar această reducere progresivă trebuie să asigure condiția de ieșire din recursivitate. De aici rezultă cele două elemente ce descriu o funcție recursivă: -
Cazul de bază: se implementează condiția de oprire; Cazul general: conține prelucrările necesare reducerii problemei și conține auto -apelul. Pagină | 2
II. Exemple de utilizare 1. Algoritmi elementari Algoritmul lui Euclid
int euclid(int a, int b) { if(b==0) return a; else return euclid(b, a%b); }
Prelucrarea cifrelor unui număr int suma(int n) { if(n==0) return 0; else return n%10+suma(n/10); }
Conversia intre baze de numeraț ie void baza2(int n) { if(n) { baza2(n/2); cout<
2. Prelucrarea tablourilor de memorie Prelucrarea se poate face începând cu primul element al tabloului și terminând cu ultimul, sau invers.
Căutarea unui element într -un vector. int cauta(int x, int a[], int n) { if(n==0) return x==a[n]; else if (x==a[n]) return 1; else return cauta(x, a, n-1); }
Pagină | 3
Căutare binară int cbin(int s, int d, int a[], int x) { int m; m=(s+d)/2; if(s>d) return -1; else if (x==a[m]) return m+1; else if(x>a[m]) return cbin(m+1, d, a, x); else return cbin(s, m-1, a, x); }
3. Recursivitatea în cascadă Calcului recursiv al termenului de rang n al șirului lui Fibonacci este un exemplu de recursivitate în cascadă. Apelul recursiv se execută de două ori în cazul general.
() () () int fibonacci(int n) { if(n<=1) return n; else return fibonacci(n-1)+fibonacci(n-2); }
În acest caz un algoritm iterativ ar fi mult mai eficient.
III. Aplicații propuse #822 NrCifreZeroRec
Cerinţa Să se scrie o funcție C++ recursivă care să returneze numărul de cifre egale cu zero ale unui număr natural transmis ca parametru.
Restricţii şi precizări numele funcției va fi nr_cif_zero funcția va avea un parametru reprezentând numărul dat numărul pentru care se calculează numărul de cifre egale cu zero va fi mai mic decât 2.000.000.000 Exemplu nr_cif_zero(2050) este 2. Important
Soluţia propusă va conţine doar definiţia funcţiei cerute. Prezenţa în soluţie a altor instrucţiuni poate duce erori de compilare sau de execuţie care vor avea ca efect depunctarea soluţiei.
#824 CifMaxRec
Cerinţa Să se scrie o funcție C++ recursivă care să returneze cifra maximă a unui număr natural transmis ca parametru.
Restricţii şi precizări numele funcției va fi cifmax Pagină | 4
funcția va avea un parametru reprezentând numărul dat numărul pentru care se calculează cifra maximă va fi mai mic decât 2.000.000.000 Exemplu cifmax(2050) este 5. Important
Soluţia propusă va conţine doar definiţia funcţiei cerute. Prezenţa în soluţie a altor instrucţiuni poate duce erori de compilare sau de execuţie care vor avea ca efect depunctarea soluţiei.
#834 ElimCifRec
Cerinţa Să se scrie o funcție C++ recursivă care primește ca parametri un număr natural n și o cifră c și returnează numărul obținut prin eliminarea din n a tuturor aparițiilor lui c. Restricţii şi precizări numele funcției va fi elimcif funcția va avea doi parametri, în această ordine: n, c, cu semnificația de mai sus 1 ≤ n ≤ 2.000.000.000, 0 ≤ c < 10 Exemplu elimcif(2454 , 4) este 25. elimcif(1157, 8) este 1157. Important
Soluţia propusă va conţine doar definiţia funcţiei cerute. Prezenţa în soluţie a altor instrucţiuni poate duce erori de compilare sau de execuţie care vor avea ca efect depunctarea soluţiei.
#925 VectorMaxMinSumRec
Cerinţa Scrieți definiția completă a subprogramului recursiv P care primeşte prin intermediul parametrului n un număr natural nenul (n≤100), iar prin intermediul parametrului x un tablou unidimensional cu n componente întregi, de maximum opt cifre fiecare. Subprogramul furnizează prin intermediul parametrului mini valoarea minimă din tabloul x, prin intermediul parametrului maxi valoarea maximă din x, iar prin intermediul parametrului sum suma elementelor din tabloul x.
Restricţii şi precizări 0 < n <= 100 numele subprogramului cerut este P
parametrii sunt, în această ordine: x, n, mini, maxi, sum elementele vectorului x sunt indexate de a zero
Se recomandă realizarea unei soluții recursive. Exemplu
Dacă n=6 și x= (12, 7, 6, 3, 8, 5), după apel mini=3, maxi=12 și sum=41. Important
Soluţia propusă va conţine doar definiţia subprogramului cerut. Prezenţa în soluţie a altor instrucţiuni poate duce erori de compilare sau de execuţie care vor avea ca efect depunctarea soluţiei.
Bombe
Cerința Se dau n bombe, num erotate de la 1 la n, pentru fiecare cunoscându -se coordonatele (x,y) unde sunt
plasate și raza de distrugere r. La explozia unei bombe se va distruge totul în interiorul și pe cercul de centru (x,y) și raza r, iar dacă exista alte bombe în această zona, acestea vor exploda la rândul lor. Se dă indicele k al primei bombe care explodează și se cere să se calculeze câte bombe rămân neexplodate. Restricţii şi precizări Datele se citesc din fișierul bombe.in și rezultatele se vor afișa în fișierul bombe.out. În fișierul bombe.in pe prima linie se află numerele n si k, iar pe următoarele n linii coordonatele și Pagină | 5
razele de distrugere ale celor n bombe. n si k sunt numere naturale, coordonatele numere întreg i, iar razele numere naturale. Exemplu: bombe.in 85 454 -3 -4 1 411 213 222 112 -1 1 2 -3 3 3 bombe.out 3 Explicatie: Prima explodeaza bomba rosie (a 5-a), ea declanseaza cele doua bombe verzi, i ar fiecare dintre cele verzi declaseaza cate una albastra. Bombele negre raman neexplodate.
Pagină | 6