Documente Academic
Documente Profesional
Documente Cultură
S8. Subprograme Recursive. Divide Et Impera
S8. Subprograme Recursive. Divide Et Impera
Enunțuri:
11. Scrieți un subprogram recursiv care calculează (aranjamente de n luate câte k), precum și
programul apelator.
12. Să se scrie subprogramul recursiv care determină rezultatul ridicării unei matrice la o putere
dată, precum și programul apelator.
13. Scrieți un subprogram recursiv care rezolvă problema turnurilor din Hanoi. Se va oferi un
exemplu de apel.
Se vor studia ambele metode de scriere a unui subprogram recursiv (metoda reducerii și metoda
descompunerii).
1
1. Să se scrie subprogramul recursiv care determină numărul de elemente negative dintr-
un vector. Se va scrie și programul apelator.
a) Metoda reducerii unei probleme de grad n la o problema de grad n-1 și o problema primitiva
(verificarea unui element din vector)
#include<stdio.h>
int numara(float v[], int n)
{ int nr;
if( n == 0) nr = 0;
else {
nr=numara(v,n-1);nr+=(v[n-1]<0)?1:0;
}
return nr;
}
void main()
{ int n,i, rez; float x[100];
printf("n="); scanf("%d", &n);
for(i=0;i<n;i++)
{printf("x[%d]=", i);scanf("%f", &x[i]);}
rez=numara(x,n);
printf("numarul de elemente negative este %d ", rez);
}
b) Metoda descompunerii unei probleme în două subprobleme (doi vectori) cu rezolvare similară
(până la probleme primitive – cu rezolvare imediată, anume vectori cu un singur element)
#include<stdio.h>
int numara(float v[], int ls, int ld)
{ int nr;
if( ls==ld) nr = (v[ls]<0)?1:0;
else {
nr=numara(v,ls, (ls+ld)/2)+numara(v,(ls+ld)/2+1, ld);
}
return nr;
}
void main()
{ int n,i, rez; float x[100];
printf("n="); scanf("%d", &n);
for(i=0;i<n;i++)
{printf("x[%d]=", i);scanf("%f", &x[i]);}
rez=numara(x,0, n-1);
printf("numarul de elemente negative este %d ", rez);
2
}
2. Să se scrie subprogramul recursiv care determină produsul scalar dintre doi vectori. Se
va scrie și programul apelator.
#include<stdio.h>
//metoda reducerii
float ps(float *x, float *y, int n)
{ float s;
if (n==0) s=0;
else s= ps(x,y,n-1)+x[n-1]*y[n-1];
return s;
}
//metoda de descompunere
float ps1(float *x, float *y, int ls, int ld)
{ float s;
if( ls==ld) s= x[ls]*y[ls];
else {
s=ps1(x,y,ls, (ls+ld)/2)+ps1(x,y,(ls+ld)/2+1, ld);
}
return s;
}
void main()
{ int n,i; float x[100], y[100], rez;
printf("n="); scanf("%d", &n);
for(i=0;i<n;i++)
{printf("x[%d]=", i);scanf("%f", &x[i]);}
for(i=0;i<n;i++)
{printf("y[%d]=", i);scanf("%f", &y[i]);}
rez=ps(x,y,n);
printf("produsul scalar este %5.2f \n", rez);
rez=ps1(x,y,0, n-1);
printf("produsul scalar in varianta doi este %5.2f ", rez);
}
3
3. Să se scrie subprogramul recursiv care determină cmmdc dintre două numere naturale.
Se va oferi și un exemplu de apel.
#include<stdio.h>
int cmmdc_2(int a, int b)
{
int rez;
if (a%b==0) rez= b;
else rez= cmmdc_2(b,a%b);
return rez;
}
void main()
{
int a,b, cmmdc;
printf("a="); scanf("%d", &a);
printf("b="); scanf("%d", &b);
cmmdc=cmmdc_2(a,b);
printf("cmmdc=%d", cmmdc);
}
#include<stdio.h>
unsigned int cmmdc_2(unsigned int a, unsigned int b)
{
unsigned int rez;
if (a%b==0) rez= b;
else rez= cmmdc_2(b,a%b);
return rez;
}
void main()
{
unsigned int x[100], cmmdc;
int n,i;
printf("n="); scanf("%d", &n);
for(i=0;i<n;i++)
4
{printf("x[%d]=", i);scanf("%u", &x[i]);}
cmmdc=cmmdc_n(x,n);
printf("cmmdc=%u", cmmdc);
}
#include<stdio.h>
//metoda reducerii
int suma(int *v, int n)
{ int s;
if (n==0) s=0;
else s= suma(v,n-1) + (v[n-1]%2==1)*v[n-1];
return s;
}
//metoda descompunerii
int suma2(int *v, int ls, int ld)
{ int s;
if (ls==ld) s=(v[ls]%2==1)*v[ls];
else s= suma2(v,ls, (ls+ld)/2) + suma2(v, (ls+ld)/2+1, ld);
return s;
}
void main()
{
int x[100], s;
int n,i;
printf("n="); scanf("%d", &n);
for(i=0;i<n;i++)
{printf("x[%d]=", i);scanf("%d", &x[i]);}
s=suma(x,n);
printf("suma numerelor impare este=%d\n", s);
s=suma2(x,0,n-1);
printf("suma numerelor impare in varianta doi este=%d", s);
}
5
6. Să se scrie subprogramul recursiv care determină produsul primelor n numere impare.
#include<stdio.h>
int produs(int n)
{
int rez;
if(n==1) rez=1;
else
rez=(2*n-1)*produs(n-1);
return rez;
}
void main()
{
int n;
printf("n="); scanf("%d", &n);
printf("produsul primelor %d numere impare=%d", n, produs(n));
}
7. Să se scrie subprogramul recursiv care determină suma cifrelor unui numar intreg.
#include<stdio.h>
int suma(int n)
{ int rez;
if(!n) rez=0;
else rez= n%10+suma(n/10);
return rez;
}
void main()
{
int n;
printf("n="); scanf("%d", &n);
printf("suma cifrelor este=%d", suma(n));
}
8. Metoda bisectiei
Funcţia are ca parametri de intrare capetele intervalului în care se caută soluţia (x0 şi x1),
numărul maxim de iteraţii (n), precizia dorită (eps), funcţia asociată ecuaţiei (f) şi adresa unde se
va înscrie soluţia. Prin numele funcţiei se returnează un cod de eroare cu următoarea
semnificaţie: 0 – nu s-a găsit soluţie datorită numărului prea mic de iteraţii sau preciziei prea
6
mari cerute; 1 – s-a obţinut soluţia exactă; 2 – s-a obţinut o soluţia aproximativă; 3 – intervalul
dat nu conţine nici o soluţie.
#include <stdio.h>
#include<math.h>
float f(float x)
{ return (pow(x,2)-5*pow(x,1)+6);
}
7
9. Să se scrie subprogramul recursiv care determină un număr la o putere (x n), precum și
programul apelator.
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<conio.h>
void main()
{
float x, rez; int n;
printf("n=");
scanf("%d", &n);
printf("x=");
scanf("%f", &x);
rez = putere(x, n);
printf("rezultatul este %5.2f", rez);
10. Să se scrie subprogramul recursiv care calculează valoarea unui polinom într-un punct
dat, precum și programul apelator.
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<conio.h>
11. Scrieți un subprogram recursiv care calculează (aranjamente de n luate câte k),
precum și programul apelator.
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<conio.h>
void main()
{
int n,k;
printf("n="); scanf("%d", &n);
printf("k="); scanf("%d", &k);
int rez = aranjamente(n, k);
printf("aranjamete =%d", rez);
}
9
12. Să se scrie subprogramul recursiv care determină rezultatul ridicării unei matrice la o
putere dată, precum și programul apelator.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
}
void main()
{
int m, p, j, i; float a[10][10], b[10][10];
printf("\n Matricea 1");
printf("\nNr de linii/coloane= "); scanf("%d", &m);
for (i = 0; i < m; i++)
for (j = 0; j < m; j++)
{
printf("a[%d][%d]= ", i, j); scanf("%f", &a[i][j]);
}
for (i = 0; i < m; i++)
{
for (j = 0; j < m; j++) printf(" %5.2f ", a[i][j]); printf("\n");
}
printf("Puterea este: "); scanf("%d", &p);
matrice_putere(a, b, m, p);
for (i = 0; i < m; i++)
{
for (j = 0; j < m; j++)
printf(" %5.2f ", b[i][j]); printf("\n");
}
}
10
13. Scrieți un subprogram recursiv care rezolvă problema turnurilor din Hanoi.
Problema turnurilor din Hanoi este următoarea: se dau trei tije verticale (fie ele 1, 2, 3), și un n
discuri de diametre diferite, cu o gaură în centru, prin care poate trece o tijă. În situația inițială
toate discurile sînt introduse pe tija 1. Regulile sînt următoarele: a) un disc mai mare nu poate fi
pus peste un disc mai mic; la o mutare se poate muta un singur disc de pe o tijă pe alta. Situația
inițială respectă regula a), discurile fiind așezate în ordine descrescătoare a diametrelor, de la
bază spre vîrf. Se cere să se găsească o serie de mutări, prin care toate discurile să fie mutate pe
tija 3.
Subprogramul următor memorează mutările necesare într-o matrice cu două coloane, în care
fiecare linie descrie o mutare, elementul de pe prima coloană fiind tija sursă, cel de pe a doua
coloană este tija destinație. Această matrice și numărul de mutări (numărul de linii) constituie
parametri de intrare/ieșire la fiecare apel.
#define _CRT_SECURE_NO_WARNINGS
//I: n, tija initiala, tija finala, tija interm., rezultat, nr mutari
//E: rezultat, nr mutari
#include<stdio.h>
void turnuri_hanoi(int n, int ti, int tf, int tint, int rez[][2], int* nr)
{
11
if (n == 1)
{
rez[*nr][0] = ti;
rez[*nr][1] = tf;
(*nr)++;
}
else
{
turnuri_hanoi(n - 1, ti, tint, tf, rez, nr);
rez[*nr][0] = ti;
rez[*nr][1] = tf;
(*nr)++;
turnuri_hanoi(n - 1, tint, tf, ti, rez, nr);
}
}
void main()
{
int i, n, mutari[100][2], nrm;
printf("numarul de discuri="); scanf("%d", &n);
nrm = 0;
turnuri_hanoi(n, 1, 3, 2, mutari, &nrm);
for (i = 0; i < nrm; i++)
printf("%d, %d\n", mutari[i][0], mutari[i][1]);
}
12