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 parametri ai altor funcii.

funciilor

ca

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

funcii:

folosit pentru a calcula maximul oricrei

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) { } double calc_f (double n) { } return n*n+4*n-3; return tan(n);

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 Tipul

care sorteaz elementele unui vector

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

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 S

se calculeze derivata unei funcii ntr-un punct.

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.


ales depinde de competena/pregtirea programatorului.

Algoritmul

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(3) * 4 factorial(2) * 3 factorial(1) * 2 factorial(0) * 1 1 1 2 6 24 120

+ Subprograme recursive
fib(n) = fib(n-1) + fib(n-2), fib( 1 ) = fib( 0 ) = 1

fib( 3 ) fib( 2 ) fib( 1 ) 1 fib( 0 ) 1 2 fib( 1 ) 1 3

fib: N fib(n) =

N (Fibonacci)

1 dac n = 0 sau n = 1 fib(n-2)+fib(n-1) dac n >1

+ Subprograme recursive

Fibonacci iterativ

Fibonacci recursiv

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; }

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. 2. 3.

instruciunea iterativ dispare condiia de la instruciunea iterativ devine (eventual modificat) condiie de oprire a generrii de noi autoapeluri

Repetarea este asigurat prin autoapel

Subprograme recursive - exemple


Calculul combinrilor de n luate cte k

C 1 C 1
k n

0 n

k k

k Cn

n! k! n k !

k n 1

k 1 n 1

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); }

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