Ce vei învăța astăzi?
După această lecție vei construi un proiect integrat care combină mai multe funcții recursive (factorial, suma cifrelor, Fibonacci, CMMDC) într-o aplicație cu meniu.
Structura unui proiect integrat
Un proiect integrat îmbină mai multe noțiuni într-o singură aplicație. Vom construi o aplicație cu meniu care permite utilizatorului să aleagă operația: factorial, suma cifrelor, termen Fibonacci sau CMMDC. Fiecare operație este implementată ca o funcție recursivă.
| Opțiune | Funcție recursivă | Caz de bază |
|---|---|---|
| 1. Factorial | factorial(n) | n == 0 → 1 |
| 2. Suma cifrelor | suma_cifre(n) | n == 0 → 0 |
| 3. Fibonacci | fib(n) | n == 0 → 0, n == 1 → 1 |
| 4. CMMDC | cmmdc(a, b) | b == 0 → a |
Programul complet cu meniu
#include <iostream>
using namespace std;
long long factorial(int n)
{
if (n == 0)
return 1;
return n * factorial(n - 1);
}
int suma_cifre(int n)
{
if (n == 0)
return 0;
return n % 10 + suma_cifre(n / 10);
}
long long fib(int n)
{
if (n == 0)
return 0;
if (n == 1)
return 1;
return fib(n - 1) + fib(n - 2);
}
int cmmdc(int a, int b)
{
if (b == 0)
return a;
return cmmdc(b, a % b);
}
int main()
{
int opt, n, a, b;
do
{
cout << "1. Factorial" << endl;
cout << "2. Suma cifrelor" << endl;
cout << "3. Fibonacci" << endl;
cout << "4. CMMDC" << endl;
cout << "0. Iesire" << endl;
cout << "Optiunea: ";
cin >> opt;
if (opt == 1)
{
cout << "n = ";
cin >> n;
cout << factorial(n) << endl;
}
else if (opt == 2)
{
cout << "n = ";
cin >> n;
cout << suma_cifre(n) << endl;
}
else if (opt == 3)
{
cout << "n = ";
cin >> n;
cout << fib(n) << endl;
}
else if (opt == 4)
{
cout << "a b = ";
cin >> a >> b;
cout << cmmdc(a, b) << endl;
}
} while (opt != 0);
return 0;
}
Observă: toate funcțiile recursive sunt definite înainte de main și sunt apelate în funcție de opțiunea aleasă.
Cum testăm proiectul?
Cazuri de test
- Opțiunea 1, n = 5 → 120
- Opțiunea 2, n = 1234 → 10
- Opțiunea 3, n = 10 → 55
- Opțiunea 4, a = 48, b = 18 → 6
- Opțiunea 0 → programul se termină
Exercițiu de completare
Completează enunțul despre proiectul integrat cu cuvintele potrivite:
Proiectul integrat combină mai multe funcții ______ într-o singură aplicație. Utilizatorul alege din ______ operația dorită. Funcțiile sunt definite înainte de ______. Opțiunea ______ termină programul.
Bancă de cuvinte:
Exercițiu de completare
Completează fragmentul de meniu din codul C++:
Bancă de cuvinte:
Test de înțelegere
Test rapid - proiect integrat:
1. Cu opțiunea 1 și n = 5, aplicația afișează:
2. Opțiunea 4 calculează:
3. Structura repetitivă folosită pentru meniu este:
Aprofundare
Modularizarea aplicației. Fiecare funcție recursivă (factorial, fib, cmmdc, suma_cifre) este definită separat, înaintea funcției main. Această separare permite testarea fiecărei funcții independent și refolosirea ei în alte programe. Într-o aplicație reală, funcțiile ar putea fi mutate în fișiere separate (biblioteci) cu anteturi proprii.
Validarea intrărilor. O aplicație robustă verifică opțiunile și valorile citite: dacă utilizatorul introduce o opțiune inexistentă, programul trebuie să afișeze un mesaj și să reafișeze meniul, fără să se termine cu eroare. Validarea valorilor (de exemplu n ≥ 0 pentru factorial) previne apelurile recursive infinite.
Structura do-while pentru meniu. Bucla do...while este alegerea clasică pentru un meniu deoarece meniul trebuie afișat cel puțin o dată, iar ieșirea din buclă se decide după citirea opțiunii. Compară cu while, care verifică condiția înainte de prima iterație.
Extinderea aplicației. Adăugarea unei noi opțiuni (de exemplu numărul de cifre sau Turnurile din Hanoi) presupune: definirea noii funcții recursive, adăugarea opțiunii în afișarea meniului și o nouă ramură if în structura de decizie. Această extensibilitate este principalul avantaj al modularizării.
PbInfo - Aplicație cu meniu
Enunț:
Cerință: Se construiește o aplicație cu meniu: opțiunea 1 calculează factorialul lui n, opțiunea 2 calculează suma cifrelor lui n, opțiunea 3 calculează fib(n), opțiunea 0 termină programul. Să se implementeze aplicația folosind funcții recursive.
Date de intrare:
Programul citește opțiunea, apoi datele necesare operației alese.
Date de ieșire:
Programul va afișa rezultatul operației alese.
Restricții și precizări:
n este număr natural, 0 ≤ n ≤ 20 pentru factorial și Fibonacci.
Exemplu:
Intrare:
1 5 0
Ieșire:
120
Cum gândim soluția:
- Definim funcțiile recursive: factorial, suma_cifre, fib
- În main afișăm meniul și citim opțiunea
- În funcție de opțiune, citim datele și apelăm funcția corespunzătoare
- Repetăm până când opțiunea este 0
Scrie soluția în C++:
Soluție corectă:
#include <iostream>
using namespace std;
long long factorial(int n)
{
if (n == 0)
return 1;
return n * factorial(n - 1);
}
int suma_cifre(int n)
{
if (n == 0)
return 0;
return n % 10 + suma_cifre(n / 10);
}
long long fib(int n)
{
if (n == 0)
return 0;
if (n == 1)
return 1;
return fib(n - 1) + fib(n - 2);
}
int main()
{
int opt, n;
do
{
cout << "1. Factorial" << endl;
cout << "2. Suma cifrelor" << endl;
cout << "3. Fibonacci" << endl;
cout << "0. Iesire" << endl;
cout << "Optiunea: ";
cin >> opt;
if (opt == 1) { cin >> n; cout << factorial(n) << endl; }
else if (opt == 2) { cin >> n; cout << suma_cifre(n) << endl; }
else if (opt == 3) { cin >> n; cout << fib(n) << endl; }
} while (opt != 0);
return 0;
}
Ce învățăm: un proiect integrat combină subprograme recursive cu o structură de meniu.
PbInfo - Aplicație completă
Enunț:
Cerință: Extinde aplicația cu meniu: opțiunea 4 calculează cmmdc(a, b), iar opțiunea 5 afișează n! + fib(n) (suma dintre factorialul lui n și termenul Fibonacci n). Să se implementeze aplicația cu funcții recursive.
Date de intrare:
Programul citește opțiunea și datele necesare operației alese.
Date de ieșire:
Programul va afișa rezultatul operației alese.
Restricții și precizări:
Valorile încap în tipul long long.
Exemplu:
Intrare:
4 48 18 0
Ieșire:
6
Cum gândim soluția:
- Adăugăm funcția recursivă cmmdc(a, b)
- Pentru opțiunea 4 citim a și b și afișăm cmmdc(a, b)
- Pentru opțiunea 5 citim n și afișăm factorial(n) + fib(n)
Scrie soluția în C++:
Soluție corectă:
#include <iostream>
using namespace std;
long long factorial(int n)
{
if (n == 0)
return 1;
return n * factorial(n - 1);
}
long long fib(int n)
{
if (n == 0)
return 0;
if (n == 1)
return 1;
return fib(n - 1) + fib(n - 2);
}
int cmmdc(int a, int b)
{
if (b == 0)
return a;
return cmmdc(b, a % b);
}
int main()
{
int opt, n, a, b;
do
{
cout << "1. Factorial" << endl;
cout << "2. Suma cifrelor" << endl;
cout << "3. Fibonacci" << endl;
cout << "4. CMMDC" << endl;
cout << "5. Factorial + Fibonacci" << endl;
cout << "0. Iesire" << endl;
cout << "Optiunea: ";
cin >> opt;
if (opt == 1) { cin >> n; cout << factorial(n) << endl; }
else if (opt == 2) { cin >> n; cout << n % 10 + n / 10 % 10 << endl; }
else if (opt == 3) { cin >> n; cout << fib(n) << endl; }
else if (opt == 4) { cin >> a >> b; cout << cmmdc(a, b) << endl; }
else if (opt == 5) { cin >> n; cout << factorial(n) + fib(n) << endl; }
} while (opt != 0);
return 0;
}
Ce învățăm: proiectele integrate pot combina rezultatele mai multor funcții recursive într-o singură operație.
Exercițiul Practic: Proiectul tău recursiv
Sarcini de lucru
Construiește și testează propria aplicație recursivă
Sarcina 1: Meniu cu 3 operații
Cerință: Scrie un program C++ cu meniu care oferă: 1) factorialul lui n, 2) suma cifrelor lui n, 3) cmmdc(a, b), 0) ieșire. Toate operațiile folosesc funcții recursive. Testează cu n = 5 (120), n = 123 (6), a = 12, b = 18 (6).
Soluție pentru Sarcina 1:
#include <iostream>
using namespace std;
long long factorial(int n)
{
if (n == 0)
return 1;
return n * factorial(n - 1);
}
int suma_cifre(int n)
{
if (n == 0)
return 0;
return n % 10 + suma_cifre(n / 10);
}
int cmmdc(int a, int b)
{
if (b == 0)
return a;
return cmmdc(b, a % b);
}
int main()
{
int opt, n, a, b;
do
{
cout << "1. Factorial" << endl;
cout << "2. Suma cifrelor" << endl;
cout << "3. CMMDC" << endl;
cout << "0. Iesire" << endl;
cout << "Optiunea: ";
cin >> opt;
if (opt == 1) { cin >> n; cout << factorial(n) << endl; }
else if (opt == 2) { cin >> n; cout << suma_cifre(n) << endl; }
else if (opt == 3) { cin >> a >> b; cout << cmmdc(a, b) << endl; }
} while (opt != 0);
return 0;
}
Sarcina 2: Raport de testare
Cerință: Rulează aplicația de la Sarcina 1 și completează tabelul de testare cu rezultatele obținute pentru fiecare opțiune.
Soluție pentru Sarcina 2:
Opțiunea 1, n = 5 -> 120 Opțiunea 2, n = 123 -> 6 Opțiunea 3, a = 12, b = 18 -> 6 Opțiunea 0 -> programul se termină