Sunteți pe pagina 1din 36

+

Algoritmi i tehnici de
programare


Cursul 2
+
Cuprins
Pointeri la funcii
Iterativitate i recursivitate
Subprograme recursive
Divide et Impera


+
Pointeri la funcii
Numele unei funcii poate fi folosit ca pointer constant
(asemntor masivelor)
Semnificaia:
adresa din memorie unde se afl codul executabil al
subprogramului respectiv
Tipul:
Pointer ctre un subprogram care primete o list de
parametri i ntoarce un anumit tip de rezultat
Utilizare:
Transmiterea subprogramelor ca parametri pentru alte
subprograme

+
Pointeri la funcii
Se utilizeaz pentru transmiterea funciilor ca
parametri ai altor funcii.
Sintaxa de definire: asemntoare sintaxei de
definire a funciilor.
n forma general, o funcie se declar astfel:
tip_returnat nume_functie(lista_parametri);
Un pointer la funcie se declar:
tip_returnat (*nume_variabila_pointer_funcie)(lista_parametri);
+
Pointeri la funcii
Dac dorim ca funcia f s apeleze funcia g sub forma f(g),
funcia g avnd antetul:
float g(int x)
atunci antetul funciei f trebuie s fie de forma:
double f (float (* pfunctie) (int))
apelul:
double rez = f(g);

+
Pointeri la funcii
Funcia folosit pentru a calcula maximul oricrei
funcii:

double max(double (*ptfunctie)(double))
+
Pointeri la funcii
double calc_sin_cos (double n)
{ return sin(n) + cos(n);
}
double calc_cos (double n)
{ return cos(n);
}


double calc_tan(double n)
{ return tan(n);
}
double calc_f (double n)
{ return n*n+4*n-3;
}

Mai multe tipuri de funcii
care vor fi apelate de o
singur funcie n care se
calculeaz maximul pentru
fiecare.


+
Pointeri la funcii
double max(double n, double (*ptfunctie)(double ) )
{ double i, valoare;
double max = 0;
for (i=0; i<n; i++)
{
valoare = (*ptfunctie)(i);
if (max < valoare)
max = valoare;
}
return max;
}


+
Pointeri la funcii
void main()
{
double n;
printf("n="); scanf("%lf",&n);
printf("Maxim pentru sinus: %8.5lf\n", max( n, calc_sin_cos));
printf("Maxim pentru cosinus: %8.5lf\n", max( n, calc_cos));
printf("Maxim pentru tangenta: %8.5lf\n", max( n, calc_tan));

double(*pf)(double);
pf = calc_f;
printf("Maxim pentru functie: %8.2lf\n", max( n, pf));
}
+
Pointeri la funcii
Funcia care sorteaz elementele unui vector
Tipul sortrii se stabilete printr-o funcie care este
trimis ca parametru funciei de sortare

void sorteaza(float v[], int n, int (*dir)(int, int));

+
Pointeri la funcii
int asc(int a, int b)
{
retun (a > b);
}

int desc(int a, int b)
{
if (a < b) return 1;
else return 0;
}
void schimba(int *a, int *b)
{
int aux = *a; *a = *b; *b = aux;
}

+
Pointeri la funcii
void sorteaza(int v[], int n, int (*dir)(int, int))
{
for (int i=0; i < n -1; i++)
{
for (int j = i; j < n; j++)
{
if ((*dir)(v[i], v[j])==1)
{
schimba(&v[i], &v[j]);
}
}
}
}

+
Pointeri la funcii
Apel
void main()
{
int x[10], n;
...
sorteaza(x, n, asc);
sau
sorteaza(x, n, desc);
}
+
Pointeri la funcii
Metoda biseciei pentru rezolvarea unei ecuaii transcendenete
a b sol
+
Pointeri la funcii
double calc_f(double x)
{
return x*x-4*x+3;
}

+
Pointeri la funcii
void bisectie(double a, double b, long n, double eps, double (*pf)(double), int *
cod, double *sol)
{
*cod = 0;
if (pf(a) * pf(b)<=0)
while ((n) && (*cod==0))
{
*sol=(a+b)/2;
if (pf(*sol)==0)
*cod=1;
if (fabs(a-b)<=eps)
*cod=2;
else I
f(pf(*sol) * pf(a)<0)
b=*sol;
else
a=*sol;
n--;
}
}
+
Pointeri la funcii
void main()
{
double a, b, eps, x;
int cod; long n;
printf("captele intervalului:");
scanf("%lf %lf", &a, &b);
printf("eroarea admisa:");
scanf("%lf",&eps);
printf("numarul maxim de iteratii:");
scanf("%ld",&n);
bisectie(a, b, n, eps, calc_f, &cod, &x);
if (cod==0) printf("nu se poate calcula solutia aproximativa");
else printf("solutia aproximativa este:%5.2lf",x);
}
+
Pointeri la funcii
Pot fi memorai n masive.
Permit apeluri de funcii dup regulile de lucru cu
masive.



+
Pointeri la funcii
float produs(int n, int v[])
{
int i;
float p;
p=1;
for(i=0;i<n;i++)
p=p*v[i];
return p;
}
float suma(int n, int v[])
{
int i;
float s;
s=0;
for(i=0;i<n;i++)
s=s+v[i];
return s;
}

void main()
{
int i, n, v[20];
printf("n=");
scanf("%d",&n);
for(i=0;i<n;i++)
{
printf("v[%d]=",i);
scanf("%d",&v[i]);
}
float (*p[2])(int, int *);
p[0] = produs;
p[1] = suma;
for (i=0; i<2; i++)
printf("%f",(*p[i])(n,v));
printf("\n");
}
+
Pointeri la funcii
S se calculeze derivata unei funcii ntr-un punct.
S se calculeze soluia unei ecuaii folosind Metoda
Tangentei.



+
Subprograme iterative
Algoritmi iterativ repetitiv

long factorial(int n)
{
int i;
long p;
p=1;
for(i=0; i<n; i++)
p=p*(i+1);
return p;
}
+
Subprograme recursive
Recursivitatea este noiune matematic care
implic definirea unui concept prin referirea la
acelai concept.

Algoritm recursiv - algoritm care se autoapeleaz
+
Subprograme recursive
Tipuri de recursivitate:
Recursivitate simpl (algoritm unirecursiv) apelul
recursiv are loc o singur dat n funcia invocat.
Recursivitate multipl (algoritm multirecursiv)
apelul recursiv se face de dou sau mai multe ori
n funcia invocat.
Trebuie s existe:
Formul de start (una sau mai multe)
Formul recursiv
+
Subprograme recursive
Exemple

Numrarea valorilor care ndeplinesc o condiie
Suma elementelor unui vector
Algoritmul lui Euclid
irul lui Fibonacci
CMMDC sau CMMMC
+
Subprograme recursive
Orice algoritm iterativ poate fi transcris ntr-un
algoritm recursiv i invers.
Algoritmul ales depinde de competena/pregtirea
programatorului.
Uzual, volumul de munc pentru scrierea
algoritmului recursiv este mai mic dect n cazul
algoritmului iterativ.
+
Subprograme recursive
Construcia subprogramelor recursive
S asigure respectarea finititudinii algoritmului: ieirea
dup un numr finit de pai

Condiie de oprire sau a generrii de noi apeluri
Aplicarea formulei de start dac e ndeplinit condiia
Aplicarea formulei recursive n caz contrar

long factorial(int n)
{
if (n == 0) return 1;
else
return n * factorial(n-1);
}
+
Subprograme recursive
Necesarul de memorie
La fiecare apel se aloc spaiu n stiv pentru x = factorial(5);
factorial( 5 )
factorial(4) * 5
factorial(0) * 1
factorial(1) * 2
factorial(2) * 3
factorial(3) * 4
120
6
2
1
1
24
+
Subprograme recursive
fib(n) = fib(n-1) + fib(n-2),
fib( 1 ) = fib( 0 ) = 1
fib( 3 )
fib( 0 )
fib( 1 )
fib( 2 )
3
2
1
1
fib( 1 )
1
fib: N N (Fibonacci)
1 dac n = 0 sau n = 1
fib(n) =
fib(n-2)+fib(n-1) dac n >1
+
Subprograme recursive
Fibonacci iterativ

long fibo_it (int n)
{long f1=1,f2=1,fn=1;
int i;
if (n==0 || n==1) return 1;
for (i=2;i<=n;i++)
{
fn=f1+f2;
f2=f1;
f1=fn;
}
return fn;
}
Fibonacci recursiv


long fibo (int n)
{
if ( n==0 || n==1 ) return 1;
return fibo (n-2) + fibo (n-1);
}

Apel
void main ()
{
int n;
printf("n=");
scanf ("%d", &n);
printf ("%ld", fibo(n));
printf ("%ld", fibo_it(n));
}
+
Subprograme recursive
Cnd alegem subprograme iterative/ recursive?

Consum memorie
Timp de execuie
Uurin n proiectare / implementare
Lungime cod surs
+
Subprograme recursive
Consideraii generale
Fiecare apel recursiv trebuie aplicat unei probleme mai
simple dect n pasul anterior
Rezult o metod simpl de oprire a generrii de noi apeluri

Cum se transform un subprogram iterativ n unul recursiv?
1. instruciunea iterativ dispare
2. condiia de la instruciunea iterativ devine (eventual
modificat) condiie de oprire a generrii de noi autoapeluri
3. Repetarea este asigurat prin autoapel
+
Subprograme recursive - exemple
Calculul combinrilor de n luate cte k



long comb(unsigned n, unsigned k)
{
if (k>n) return 0;
else
if ((k==0) || (k==n))
return 1;
else
return comb(n-1,k)+comb(n-1,k-1);
}
! !
!
k n k
n
C
k
n
1 k
1 n
k
1 n
k
n
C C C
1
0
n
C
1
k
k
C
+
Subprograme recursive - exemple
Suma elementelor unui vector
S(n) = x[n-1] + S(n-1), S(0) = 0

long suma(long v[], int n)
{
if( n == 0)
return 0;
else
return v[n-1] + suma(v, n-1);
}
Apel:
long s;
s = suma(a,n);


+
Subprograme recursive - exemple
Maximul dintr-un vector
int max(int a[100], int n)
{
int x1;
if (n==0) return a[n];
else
{
x1=max(a,n-1);
if (x1>a[n]) return x1;
else return a[n];
}
}
Apel:
int m;
m = max(a,n-1);

+
Subprograme recursive - exemple
Maxim dintre dou valori
int maxd (int a, int b)
{
return a > b ? a:b;
}
Maxim dintr-un vector
int maxim (int a[100], int n)
{
if (n==1) return a[0];
else return maxd (maxim (a,n-1), a[n-1]);
}
Apel:
int m;
m = max(a,n-1);

+
Subprograme recursive - teme
Numrul de elemente negative dintr-un vector
Produs scalar ntre doi vectori
Algoritmul lui Euclid
Calculul cmmdc*
Metoda tangentei
Problema turnurilor din Hanoi*
Sortare*

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