Documente Academic
Documente Profesional
Documente Cultură
Laborator 10
Laborator 10
Recursivitate
Recursivitatea este una dintre noiunile fundamentale ale informaticii.
Def: Recursivitatea este un mecanism general de elaborare al programelor. Ea
const n posibilitatea unui subprogram de a se autoapela.
Recursivitatea a aprut din necesitatea de a transcrie direct formule
matematice recursive. n timp acest mecanism a fost extins i pentru ali
algoritmi.
Mecanismul recursivitii
Care este mecanismul prin care programele se autoapeleaz? S ne
amintim cum memoreaz programele parametrii transmii: pentru memorarea
parametrilor, subprogramele folosesc o zon de memorie numit stiv.
Memorarea parametrilor transmii se face n ordinea n care acetia figureaz
n antet: de la stnga la dreapta. Pentru parametrii transmii prin valoare,
se transmite valoarea, iar pentru cei transmii prin referin se transmite
adresa. n cadrul subprogramului, parametrii transmii i memorai n stiv
sunt variabile. Numele lor este cel din lista parametrilor formali.
Subprogramul lucreaz cu datele aflate pe un anumit nivel al stivei
pentru variabilele transmise prin valoare, dar i cu variabilele funciei
main(), dac acestea sunt transmise prin referin.
Exist posibilitatea ca subprogramul s lucreze direct cu variabilele
globale fr ca acestea s fie transmise prin referin. Dup cum tim
variabilele globale pot fi accesate din orice subprogram, dac sunt declarate
la nceputul codului surs.
n cazul unui numr foarte mare de autoapelri, exist posibilitatea ca
segmentul de stiv s se ocupe total, caz n care programul se va termina cu
eroare.
Recursivitatea presupune mai mult memorie.
O gndire recursiv exprim concentrat o anumit stare, care se repet
la infinit. Aceast gndire se aplic n elaborarea algoritmilor recursivi cu
o modificare esenial: adugarea condiiei de terminare. n absena acestei
condiii nu se poate vorbi despre un algoritm deoarece acetia sunt finii.
Pai de elaborare:
Ce se ntmpl la un nivel se ntmpl la orice nivel.
Subprogramul care se autoapeleaz trebuie s conin instruciunile
corespunztoare unui nivel.
Un algoritm recursiv se elaboreaz folosind acest tip de gndire , nu o
gndire precum cea folosit pn acum, cnd am elaborat algoritmi iterativi.
Pentru orice algoritm recursiv exist unul iterativ care rezolv aceeai
problem.
int i,n;
cout<<"Introduceti n= ";cin>>n;
for(i=1;i<=n;i++)
cout<<"Termenul "<<i<<" din sir este : "<<Fibonacci(i)<<endl;
cout<<endl;
}
void main()
{
int n;
cout<<"Introduceti n = ";cin>>n;
afiseaza(n);
cout<<"BUMMM !!!!"<<endl;
}
Problema 6. Folosind o metod recursiv, s se stabileasc dac un numr
ntreg citit de la tastatur este numr prim sau nu.
#include<iostream>
using namespace std;
bool isPrime(int p, int i) {
if(i==p) return 1;
if(p%i==0) return 0;
return isPrime(p,i+1);
}
void main()
{
int n;
cout<<"Introduceti n = ";cin>>n;
if(isPrime(n,2))
cout<<n<<" este prim !"<<endl;
else
cout<<n<<" nu este prim !"<<endl;
}
*********************************
Metoda Backtracking
Se aplic problemelor n care soluia poate fi reprezentat sub forma
unui vector x=(x1, x2, x3, xk, xn) din S, unde S este mulimea soluiilor
problemei i S=S1 S2 Sn i Si sunt mulimi finite avnd s elemente i xi
aparine lui Si .
Pentru fiecare problem se dau relaii ntre componentele vectorului x,
care sunt numite condiii interne; soluiile posibile care satisfac
condiiile interne se numesc soluii rezultat. Metoda de generare a tuturor
soluiilor posibile i apoi de determinare a soluiilor rezultat prin
verificarea ndeplinirii condiiilor interne necesit foarte mult timp.
Metoda backtracking evit aceast generare i este mai eficient.
Elementele vectorului x, primesc pe rnd valori n ordinea cresctoare a
indicilor, x[k] va primi o valoare numai dac au fost atribuite valori
elementelor x[1]...x[k-1]. La atribuirea valorii lui x[k] se verific
ndeplinirea unor condiii de continuare referitoare la x[1]...x[k-1]. Dac
aceste condiii nu sunt ndeplinite la pasul k, acest lucru nseamn c orice
valori am atribui lui x[k], x[k+1],...,x[n] nu se va ajunge la o soluie
rezultat.
sol=0;
}
void tipar(int p) {
int i,j;
sol++;
cout<<"Solutia numarul "<<sol<<" este : "<<endl;
for(i=1;i<=p;i++) {
for(j=1;j<=p;j++)
if(j==st[i])
cout<<" * ";
else
cout<<" o ";
cout<<endl;
}
cout<<"==================="<<endl;
}
int valid(int p) {
int i,ok;
ok=1;
for(i=1;i<p;i++)
if(st[p]==st[i]||abs(st[p]-st[i])==abs(p-i))
ok=0;
return ok;
}
void bktr(int p) {
int pval;
for(pval=1;pval<=n;pval++) {
st[p]=pval;
if (valid(p))
if (p==n)
tipar(p);
else bktr(p+1);
}
}
void main() {
initializari();
bktr(1);
}