Școala Româno-Britanică
Modulul 5 Clasa a X-a | C++

Ora 8: Proiect integrat: aplicație recursivă

Ce vei învăța astăzi: Cum se combină mai multe funcții recursive într-un proiect integrat (aplicație care reunește mai multe funcții într-un singur program) cu meniu în consolă (interfață text cu opțiuni numerotate)

Rezultat practic: Construiești o aplicație C++ cu meniu care folosește factorial, suma cifrelor, Fibonacci și CMMDC (Competența 6.5)

Competența 6.5 Săptămâna 28

Înainte de a începe

De ce contează? Un proiect integrat combină toate funcțiile recursive învățate și seamănă cu problema integrată de la evaluarea finală, pregătindu-te pentru punctajul maxim.

Ce știi deja?

Din ora 7, poți scrie o funcție recursivă care afișează invers un șir? Ce rol are parametrul n într-o parcurgere recursivă a unui vector?

Ideea-cheie: Un proiect integrat cu meniu separă clar citirea, validarea opțiunii (verificarea că alegerea introdusă este corectă) și apelul funcției alese, fiecare prelucrare fiind o funcție recursivă independentă.
SINTEZĂ TEORETICĂ ȘI EXEMPLE GHIDATE

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.

Combinarea mai multor funcții recursive
Meniu de aplicație în consolă
Citirea și validarea opțiunii
Proiect integrat complet

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

Algoritm aplicație cu meniu: repetă afișează meniul: 1 - Factorial 2 - Fibonacci 3 - CMMDC 4 - Suma cifrelor 0 - Ieșire citește opțiunea dacă opțiunea == 1 atunci citește n; afișează factorial(n) dacă opțiunea == 2 atunci citește n; afișează fib(n) dacă opțiunea == 3 atunci citește a, b; afișează cmmdc(a, b) dacă opțiunea == 4 atunci citește n; afișează suma_cifre(n) cât timp opțiunea != 0
Program C++ - aplicație recursivă 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:
recursive meniu main 0

Exercițiu de completare

Completează fragmentul de meniu din codul C++:
int opt, n, a, b;
______
{
    cout << "1. Factorial" << endl;
    cout << "Optiunea: ";
    ______ >> opt;
    if (opt == 1) { ... }
} ______ (opt != 0);
Bancă de cuvinte:
do cin while

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:

Ai grijă la: meniul - folosește do...while și validează opțiunea citită, altfel o opțiune greșită poate închide aplicația sau poate produce rezultate incorecte.

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.

APLICARE ȘI REZOLVARE DE PROBLEME

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:
  1. Definim funcțiile recursive: factorial, suma_cifre, fib
  2. În main afișăm meniul și citim opțiunea
  3. În funcție de opțiune, citim datele și apelăm funcția corespunzătoare
  4. 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:
  1. Adăugăm funcția recursivă cmmdc(a, b)
  2. Pentru opțiunea 4 citim a și b și afișăm cmmdc(a, b)
  3. 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ȚII PRACTICE

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ă

Scrie pe caiet

Titlul lecției

Proiect integrat: aplicație recursivă. A opta lecție din Modulul 5 îți arată cum se combină funcțiile recursive într-o aplicație cu meniu.

Definiția lecției

Un proiect integrat reunește mai multe funcții recursive într-o singură aplicație, coordonată de funcția main. Programul afișează un meniu cu opțiuni numerotate, citește alegerea utilizatorului și execută funcția corespunzătoare. Funcțiile recursive sunt definite înaintea funcției main, fiecare cu o singură responsabilitate. Structura do...while este potrivită pentru meniuri, deoarece execută corpul cel puțin o dată și apoi verifică condiția de ieșire. Validarea opțiunii previne alegerea unui număr care nu există în meniu. Opțiunea 0 termină programul, iar fiecare opțiune din meniu se testează cu cazuri concrete.

Definiții esențiale

Algoritmul cheie - pseudocod

Algoritm aplicație cu meniu: repetă afișează meniul (1-Factorial, 2-Fibonacci, 3-CMMDC, 4-Suma cifrelor, 0-Ieșire) citește opțiunea dacă opțiunea == 1 atunci citește n; afișează factorial(n) dacă opțiunea == 2 atunci citește n; afișează fib(n) dacă opțiunea == 3 atunci citește a, b; afișează cmmdc(a, b) dacă opțiunea == 4 atunci citește n; afișează suma_cifre(n) cât timp opțiunea != 0

Algoritmul cheie - cod C++

Program C++ - aplicație recursivă cu meniu
#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 suma_cifre(int n)
{
    if (n == 0)
        return 0;
    return n % 10 + suma_cifre(n / 10);
}

int main()
{
    int opt, n, a, b;
    do
    {
        cout << "1. Factorial" << endl;
        cout << "2. Fibonacci" << endl;
        cout << "3. CMMDC" << endl;
        cout << "4. Suma cifrelor" << 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 << fib(n) << endl;
        }
        else if (opt == 3)
        {
            cout << "a = ";
            cin >> a;
            cout << "b = ";
            cin >> b;
            cout << cmmdc(a, b) << endl;
        }
        else if (opt == 4)
        {
            cout << "n = ";
            cin >> n;
            cout << suma_cifre(n) << endl;
        }
    } while (opt != 0);
    return 0;
}

Greșeli comune de evitat

Exemplu practic

Scenariu real: la o librărie, casa de marcat are un meniu cu calcule; clientul alege opțiunea 1 și introduce n = 5, iar programul afișează 120. Fragmentul de meniu:

Program C++ - fragment de meniu (exemplu practic)
do
{
    cout << "1. Factorial" << endl;
    cout << "0. Iesire" << endl;
    cout << "Optiunea: ";
    cin >> opt;
    if (opt == 1)
    {
        cin >> n;
        cout << factorial(n) << endl;
    }
} while (opt != 0);

La alegerea opțiunii 1 și n = 5, programul afișează 120.

Sfaturi practice și trucuri