Sunteți pe pagina 1din 63

Programarea

calculatoarelor
Universitatea Constatin Brncui din Trgu-Jiu
Facultatea de Inginerie
Departamentul de Automatic, Energie i Mediu
Lect.dr. Adrian Runceanu
Curs 20
Recursivitate
24.01.2013 Programarea calculatoarelor 2
Coninutul cursului

1. Conceptul de recursivitate
2. Recursivitate direct
3. Recursivitate indirect
4. Relaia dintre recursivitate i iteraie
5. Exemple de programe recursive
24.01.2013 Programarea calculatoarelor 3
1. Conceptul de recursivitate
Un obiect sau un fenomen este definit n mod
recursiv dac n definitia sa se face referire la el
nsusi.
Conceptul de recursivitate ofer posibilitatea
definirii unei infinitti de obiecte printr-un
numr finit de relatii.
O functie este recursiv atunci cnd executarea
ei implic cel putin nc un apel ctre ea nssi.
24.01.2013 Programarea calculatoarelor 4
1. Conceptul de recursivitate
Tipuri de recursivitate:

1. Recursivitate direct apelul recursiv se face
chiar din functia invocat.
2. Recursivitate indirect (mutual) apelul
recursiv se realizeaz prin intermediul mai
multor functii care se apeleaz circular.
24.01.2013 Programarea calculatoarelor 5
Exemplul 1
Definirea numerelor naturale:
1 este numr natural
succesorul unui numr natural este un numr
natural
Se presupune cunoscut definiia
succesorului unui numr: acel numr obinut
din numrul dat prin adugarea unei uniti.
24.01.2013 Programarea calculatoarelor 6
Exemplul 2
Algoritm de calcul pentru factorialul unui
numr N. (notatie N!):
dac N = 0 atunci N! = 1
dac N > 0 atunci N! = N * (N-1)!
Astfel spus, factorialul unui numr N > 0 se
obine prin nmulirea numrului cu factorialul
predecesorului.
24.01.2013 Programarea calculatoarelor 7
Coninutul cursului

1. Conceptul de recursivitate
2. Recursivitate direct
3. Recursivitate indirect
4. Relatia dintre recursivitate si iteratie
5. Exemple de programe recursive
24.01.2013 Programarea calculatoarelor 8
Recursivitate direct
n limbajul C++ functiile se pot apela pe ele
nsele, adic sunt direct recursive.
Pentru o functionare corect (din punct de
vedere logic), apelul recursiv trebuie s fie
conditionat de o decizie care, la un moment dat
n cursul executiei, s mpiedice continuarea
apelurilor recursive si s permit astfel revenirea
din sirul de apeluri.
24.01.2013 Programarea calculatoarelor 9
Recursivitate direct
Lipsa acestei conditii sau programarea ei
gresit va conduce la executarea unui sir de
apeluri a crui terminare nu mai este controlat
prin program si care, la epuizarea resurselor
sistemului, va provoca o eroare de executie:
Depsirea stivei de date.

24.01.2013 Programarea calculatoarelor 10
Exemplu
void p (list de parametri){
lista variabile locale
...
p(list de parametri);
}

Conditia care trebuie testat este specific problemei de
rezolvat.
Programatorul trebuie s o identifice n fiecare situatie
concret si, pe baza ei, s redacteze corect apelul
recursiv.
Revenirea din apeluri se face n ordine invers.
24.01.2013 Programarea calculatoarelor 11
if (cond) p(list de parametri) ...
sau:
while (cond) { ...p(list de parametri) }
sau:
do ... p(list de parametri)... while (cond)
if (cond) p(list de parametri) ...
sau:
while (cond) { ...p(list de parametri) }
sau:
do ... p(list de parametri)... while (cond)
Coninutul cursului

1. Conceptul de recursivitate
2. Recursivitate direct
3. Recursivitate indirect
4. Relatia dintre recursivitate si iteratie
5. Exemple de programe recursive
24.01.2013 Programarea calculatoarelor 12
Recursivitate indirect
Un subprogram S, n corpul cruia apar apeluri la
S (la el nsui) se numete subprogram direct
recursiv iar un subprogram P, pentru care exist
un subprogram Q, astfel nct P face apeluri la Q,
iar Q conine apelul la P se numete subprogram
indirect recursiv.
n acest ultim caz, subprogramele P i Q se mai
numesc i mutual recursive.
24.01.2013 Programarea calculatoarelor 13
Recursivitate indirect
Funcie direct recursiv

functia S;
{

S; // apel la functia S

}



24.01.2013 Programarea calculatoarelor 14
Funcii mutual recursive
functia P;
{

Q ; // apel la functia Q

}
functia Q;
{

P ; // apelul functiei P

}
Coninutul cursului

1. Conceptul de recursivitate
2. Recursivitate direct
3. Recursivitate indirect
4. Relatia dintre recursivitate si iteratie
5. Exemple de programe recursive
24.01.2013 Programarea calculatoarelor 15
Relaia dintre recursivitate i
iteraie - Comparaie
Iteraia
executia repetat a unei
secvente de instructiuni
o nou iteratie se execut doar
n urma evalurii unei conditii
(la nceput sau sfrsit)
fiecare iteratie se execut pn
la capt si apoi se trece,
eventual, la o nou iteratie
se recomand atunci cnd
algoritmul de calcul este
exprimat printr-o formul
iterativ
24.01.2013 Programarea calculatoarelor 16
Recursivitatea
executia repetat a unei functii
un nou apel recursiv se execut
tot n urma evalurii unei
conditii (pe parcurs)
functia recursiv se apeleaz
din nou, nainte de terminarea
apelului precedent
se recomand doar atunci cnd
problema este prin definitie
recursiv (recursivitatea
consum resurse n exces)
Coninutul cursului

1. Conceptul de recursivitate
2. Recursivitate direct
3. Recursivitate indirect
4. Relatia dintre recursivitate si iteratie
5. Exemple de programe recursive
24.01.2013 Programarea calculatoarelor 17
Probleme rezolvate
1. Se dau doua numere intregi a si b si se cere sa
se calculeze cel mai mare divizor comun. (Algoritmul
lui EUCLID prin mpriri repetate).
Formularea recursiv, n cuvinte, a algoritmului:
Dac unul dintre numere este zero, c.m.m.d.c. al lor
este cellalt numr.
Dac nici unul dintre numere nu este zero, atunci
c.m.m.d.c. nu se modific dac se nlocuieste unul
dintre numere cu restul mprtirii sale cu cellalt.
24.01.2013 Programarea calculatoarelor 18
Probleme rezolvate
Algoritmul poate fi implementat sub forma
urmtoarei functii recursive:
int cmmdc (int n, int m)
{
if (n==0) return m;
else return cmmdc(n, m % n);
}

24.01.2013 Programarea calculatoarelor 19
Probleme rezolvate
Codul sursa al implementarii (varianta prin scaderi
succesive) este urmatorul:
#include<iostream.h>

int cmmdc(int a,int b)
{
if(a==b) return a;
else if(a>b) return cmmdc(a-b, b);
else return cmmdc(a, b-a);
}
24.01.2013 Programarea calculatoarelor 20
int main(void)
{
int a, b;
char c;
do
{
cout<<"Introduceti a= "; cin>>a;
cout<<"Introduceti b= "; cin>>b;
cout<<"C.m.m.d.c. "<<a<<","<<b<<" este
"<<cmmdc(a,b)<<endl;
cout<<"Mai doriti sa calculati pentru alte valori?
(d/n) ";
cin>>c;
}while( toupper(c)!='N' );
}
24.01.2013 Programarea calculatoarelor 21
Executia programului pentru cateva date de test:
Programarea calculatoarelor 24.01.2013 22
Probleme rezolvate

2. S se calculeze suma primelor n numere
naturale.

Soluia este dat de relaia de recuren:
suma(1, 2, . . . , n) =
suma(n, suma(1, 2, . . . , n-1))


24.01.2013 Programarea calculatoarelor 23
#include<iostream.h>

long int suma(long int i)
{
if(i==1) return 1;
else return suma(i-1)+i;
}

int main(void)
{
long int n;
cout<<"Introduceti n= "; cin>>n;
cout<<"Suma primelor "<<n<<" numere este
"<<suma(n)<<endl;
}
24.01.2013 Programarea calculatoarelor 24
Executia programului pentru o valoare de test:

Programarea calculatoarelor 24.01.2013 25
Probleme rezolvate

3. S se afle elementul maxim dintr-un vector
dat.

Soluia este dat de relaia de recuren:
maxim(a
1
, a
2
, . . . ,a
n
) =
maxim(a
n
, maxim(a
1
, a
2
, . . . , a
n-1
))
24.01.2013 Programarea calculatoarelor 26
#include<iostream.h>
int a[100],n,i;

int max(int x, int y)
{
if(x > y) return x;
else return y;
}

int maxim(int a[ ],int n)
{
if(n==1) return a[1];
else return
max(a[n],maxim(a,n-1));
}
24.01.2013 Programarea calculatoarelor 27
int main(void)
{
cout<<"Introduceti dimensiunea
sirului n = ";
cin>>n;
for(i=1;i<=n;i++)
{
cout<<"a["<<i<<"]=";
cin>>a[i];
}
cout<<"Elementul maxim din
vector este = "<<maxim(a,n);
}
Executia programului pentru cateva valori de test:
24.01.2013 Programarea calculatoarelor 28
Probleme rezolvate


4. Sa se transforme un numar n, dat in
baza 10, intr-o alta baza b (2<=b<=10).
24.01.2013 Programarea calculatoarelor 29
#include<iostream.h>
int n,b;

void baza(int n)
{
if(n<b) cout<<n;
else
{
baza(n/b);
cout<<n%b;
}
}
24.01.2013 Programarea calculatoarelor 30
int main(void)
{
cout<<"Dati numarul in baza 10,
n = ";
cin>>n;
cout<<"Dati baza in care vreti sa
se transforme ";
cin>>b;
cout<<n<<" in baza "<<b<<" este
";
baza(n);
}
Executia programului pentru cateva valori de test:

Programarea calculatoarelor 24.01.2013 31
Probleme rezolvate

5. Se citeste un numar intreg ca un sir de
caractere cu cel mult 255 cifre.
Sa se afiseze numarul cu cifrele in ordine
inversa.
24.01.2013 Programarea calculatoarelor 32
#include<iostream.h>
#include<string.h>

char n[255],i,l;

void invers(int i)
{
if(i<l) invers(i+1);
cout<<n[i];
}
24.01.2013 Programarea calculatoarelor 33
int main(void)
{
cout<<"Dati numarul in n = ";
cin>>n;
l=strlen(n);
cout<<"Numarul rasturnat este ";
invers(0);
}
Executia programului pentru o valoare de test:
Programarea calculatoarelor 24.01.2013 34
Probleme rezolvate
6. Suma puterilor rdcinilor

Fie ecuaia x
2
- Sx + P = 0 cu S, P R si x
1
, x
2

rdcinile ecuaiei.
S se calculeze S
n
= x
1
n
+ x
2
n

, n N.
24.01.2013 Programarea calculatoarelor 35
Cutm relaia de recuren pentru S
n
,
tiind c x
1
, respectiv x
2
sunt rdcinile
ecuaiei date i deci ndeplinesc relaiile:
x
1
2
- Sx
1
+ P = 0 | * x
1
n-2

x
2
2
- Sx
2
+ P = 0 | * x
2
n-2

nmulim aceste relaii cu x
1
n-2
i x
2
n-2
i
adunm relaiile obinute i rezult:
S
n
= x
1
n
+ x
2
n
=
= S * (x
1
n-1
+ x
2
n-1
) P * (x
1
n-2
+ x
2
n-2
) =
= S * S
n-1
- P * S
n-2

24.01.2013 Programarea calculatoarelor 36
Astfel am obinut o relaie de recuren:

S
0
= x
1
1
+ x
2
1
= 1 + 1 = 2, pentru n=0
S
1
= x
1
1
+ x
2
1
= S, pentru n=1
S
n
= S * S
n-1
- P * S
n-2
, pentru n 2
24.01.2013 Programarea calculatoarelor 37
#include<iostream.h>
int n;
float s,p,r;

float suma(int n)
{
if(n==0) return 2;
else if(n==1) return s;
else return(s*suma(n-1)-
p*suma(n-2));
}
24.01.2013 Programarea calculatoarelor 38
int main(void)
{
cout<<"Introduceti valorile
ecuatiei de gradul II "<<endl;
cout<<"Dati s = ";cin>>s;
cout<<"Dati p = ";cin>>p;
cout<<" N = ";cin>>n;
r=suma(n);
cout<<"Valoarea lui S("<<n<<")
este "<<r;
}
Executia programului pentru un set de valori de test:
Programarea calculatoarelor 24.01.2013 39
Probleme propuse spre rezolvare
1. S se scrie un program care s calculeze al n-lea
termen din irul lui Fibonacci, care este definit
recursiv astfel:
fib[1]=0
fib[2]=1
fib[n]=fib[n-1] + fib[n-2], pentru n>2
2. S se caute o soluie nerecursiv pentru irul lui
Fibonacci.

24.01.2013 Programarea calculatoarelor 40


Structura biletelor de examen
24.01.2013 Programarea calculatoarelor 41
Structura biletelor de examen
24.01.2013 Programarea calculatoarelor 42
Subiect I - Grile cu alegere multipl. Identificai litera care
corespunde rspunsului corect.
Subiect II - Algoritm n pseudocod

Specializarea INGINERIE ENERGETICA:
Subiect III Enunul unei probleme avnd un exemplu specificat.
Specializarea INGINERIA SISTEMELOR:
Subiect III Enunul unei probleme cu vectori sau matrici, avnd
un exemplu specificat.
Subiect IV Enunul unei probleme cu funcii, avnd un exemplu
specificat.


Structura biletelor de examen
24.01.2013 Programarea calculatoarelor 43


Subiectul III Enunul unei probleme cu vectori
sau matrici, avnd un exemplu specificat.


Problema 1
24.01.2013 Programarea calculatoarelor 44
Problema interclasrii
Se citesc dou tablouri unidimensionale cu
componente numere naturale. Fiecare tablou are
elementele sortate cresctor. Se cere s se construiasc
un al treilea tablou care conine elementele celor dou n
ordine cresctoare.
Exemplu:
Date de intrare:
n=5, x={1, 3, 15, 27, 32}
si
m=6, b={2, 4, 18, 29, 38, 55}
Date de iesire:
k = 11
z = {1, 2, 3, 4, 15, 18, 27,
29, 32, 55}
Problema 1
#include<iostream.h>
int main(void)
{
int i,n,j,m,k;
float x[50],y[50],z[100];
cout<<"Dati numarul de elemente ale tabloului X ";
cin>>n;
for(i=1;i<=n;i++)
{
cout<<"x["<<i<<"]= ";
cin>>x[i];
}
24.01.2013 Programarea calculatoarelor 45
Problema 1
cout<<"Dati numarul de elemente ale tabloului
Y ";
cin>>m;
for(j=1;j<=m;j++)
{
cout<<"y["<<j<<"]= ";
cin>>y[j];
}
24.01.2013 Programarea calculatoarelor 46
Problema 1
i=1;
j=1;
k=0;
while( (i<=n) && (j<=m) )
if(x[i]<y[j])
{ k++; z[k]=x[i]; i++; }
else
{ k++; z[k]=y[j]; j++; }
24.01.2013 Programarea calculatoarelor 47
Problema 1
if(i<=n)
for(j=i;j<=n;j++)
{ k++; z[k]=x[j]; }
else
for(i=j;i<=m;i++)
{ k++; z[k]=y[i]; }
cout<<"\nVectorul Z cu elementele
interclasate este ";
for(i=1;i<=k;i++) cout<<" "<<z[i];
}
24.01.2013 Programarea calculatoarelor 48

24.01.2013 Programarea calculatoarelor 49
Problema 2
24.01.2013 Programarea calculatoarelor 50

S se scrie un program care calculeaz minimul i
maximul dintr-o matrice cu n linii i m coloane (A
n*m
) (1<=n,
m<=30).

Exemplu:
Date de intrare:
n=3, m=4
1 2 3 4
8 7 6 5
11 22 33 7
Date de iesire:
minim = 1
maxim = 33
Problema 2
#include <iostream.h>
int main(void)
{
int n, m, min, i, j, max, a[30][30];
cout<<"Dati dimensiunile matricei \n";
cout<<"Dati numarul de linii n = ";
cin>>n;
cout<<"Dati numarul de coloane m = ";
cin>>m;
24.01.2013 Programarea calculatoarelor 51
Problema 2
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
{
cout<<"a["<<i<<","<<j<<"]= ";
cin>>a[i][j];
}
24.01.2013 Programarea calculatoarelor 52
Problema 2
cout<<"Elementele matricei A sunt: \n";
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
cout<<a[i][j]<<" ";
cout<<endl;
}
24.01.2013 Programarea calculatoarelor 53
Problema 2
// calculam minimele pentru fiecare coloana aflate doar pe
prima linie
min = a[1][1];
max = a[1][1];
for(j=2;i<=m;i++)
{
if( a[1][j] < min ) min = a[1][j];
if( a[1][j] > max ) max = a[1][j];
}
24.01.2013 Programarea calculatoarelor 54
Problema 2
for(i=2;i<=n;i++)
for(j=1;j<=m;j++)
{
if( a[i][j] < min ) min = a[i][j];
if( a[i][j] > max ) max = a[i][j];
}
cout<<"Elementul minim din matrice este "<<min<<endl;
cout<<"Elementul maxim din matrice este "<<max<<endl;
}
24.01.2013 Programarea calculatoarelor 55
Problema 2
24.01.2013 Programarea calculatoarelor 56
Problema 3
24.01.2013 Programarea calculatoarelor 57

Se consider o matrice An*m (1<=n,m<=30) cu
elemente numere ntregi. S se determine linia (liniile) din
matrice care conine(conin) cele mai multe elemente
nenule.
Exemplu:
Date de intrare:
n=3, m=4
1 0 3 -4
-8 7 0 5
0 22 0 7
Date de iesire:
Linia 1 are 3 elemente nenule
Linia 2 are 3 elemente nenule
Problema 3
24.01.2013 Programarea calculatoarelor 58
#include<iostream.h>
int main(void)
{
int a[30][30], n, m, i, j, max, nr;
cout<<"Dati numarul de linii n = "; cin>>n;
cout<<"Dati numarul de coloane m = "; cin>>m;
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
{
cout<<"a["<<i<<","<<j<<"]= ";
cin>>a[i][j];
}
Problema 3
24.01.2013 Programarea calculatoarelor 59

cout<<"\nMatricea A are elementele:\n";
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++) cout<<a[i][j]<<" ";
cout<<endl;
}
Problema 3
24.01.2013 Programarea calculatoarelor 60
max=-10000;
for(i=1;i<=n;i++)
{
nr=0;
for(j=1;j<=m;j++)
if(a[i][j]!=0) nr++;
if(max<nr) max=nr;
}
Problema 3
24.01.2013 Programarea calculatoarelor 61
for(i=1;i<=n;i++)
{
nr=0;
for(j=1;j<=m;j++)
if(a[i][j]!=0) nr++;
if(max==nr)
cout<<"Linia "<<i<<" are "<<max<<"
elemente nenule\n";
}
}

Problema 3
24.01.2013 Programarea calculatoarelor 62


ntrebri?
24.01.2013 Programarea calculatoarelor 63

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