Clasa a X-a · RecursivitateRead in English

Cmmdc recursiv în C++

În engleză: Recursive GCD

O(log n)C++1741 de linii2 exemple

Ideea

Algoritmul lui Euclid scris recursiv: cmmdc(a, 0) = a, iar cmmdc(a, b) = cmmdc(b, a % b). Autoapelul este ultima operație din funcție (recursivitate „de coadă”), deci nu mai rămâne nimic de calculat la întoarcere. Afișăm și numărul de apeluri, ca să vedem cât de repede se ajunge la rest 0.

Descrierea în engleză

Euclid's algorithm written recursively: gcd(a, 0) = a, and gcd(a, b) = gcd(b, a % b). The recursive call is the last operation in the function (tail recursion), so nothing is left to compute on the way back. We also print the number of calls, to see how quickly a remainder of 0 is reached.

Complexitate
O(log(min(a, b)))
Clasa
Clasa a X-a (Grade 10)

Exemple

Exemplul 1

Intrare

48 18

Ieșire așteptată

6 4
Exemplul 2

Intrare

7 0

Ieșire așteptată

7 1

Codul C++

Codul complet, cu comentarii în română. Îl poți modifica liber și îl poți reseta oricând.

cmmdc-recursiv.cpp
/*
 * Titlu: Cmmdc recursiv
 * Clasa: 10
 * Capitol: Recursivitate
 * Descriere: Algoritmul lui Euclid scris recursiv: cmmdc(a, 0) = a, iar
 *            cmmdc(a, b) = cmmdc(b, a % b). Autoapelul este ultima operație din
 *            funcție (recursivitate „de coadă”), deci nu mai rămâne nimic de calculat
 *            la întoarcere. Afișăm și numărul de apeluri, ca să vedem cât de repede
 *            se ajunge la rest 0.
 * Complexitate: O(log(min(a, b)))
 *
 * Exemplu
 * Intrare: 48 18
 * Ieșire: 6 4
 *
 * Exemplu
 * Intrare: 7 0
 * Ieșire: 7 1
 */
#include <iostream>
using namespace std;

int apeluri;

long long cmmdc(long long a, long long b)
{
    apeluri++;
    if (b == 0)
        return a;
    return cmmdc(b, a % b);
}

int main()
{
    long long a, b;
    cin >> a >> b;
    long long d = cmmdc(a, b);
    cout << d << ' ' << apeluri << '\n';
    return 0;
}

Rulează pe un g++ adevărat (C++17, -O2) prin Compiler Explorer. Programele trebuie să se termine repede: există o limită de timp.