Clasa a X-a · RecursivitateRead in English

Funcția Manna-Pnueli în C++

În engleză: The Manna-Pnueli function

O(n)C++1742 de linii2 exemple

Ideea

Funcția este definită astfel: f(x) = x - 1 dacă x >= 12, altfel f(x) = f(f(x + 2)). Autoapelul interior f(x + 2) se calculează primul, iar rezultatul lui devine argumentul autoapelului exterior. Pentru orice x < 12 rezultatul este 11, dar numărul de apeluri crește cu cât x este mai mic. Este un exercițiu bun de urmărire a stivei: se afișează valoarea și numărul total de apeluri.

Descrierea în engleză

The function is defined as: f(x) = x - 1 if x >= 12, otherwise f(x) = f(f(x + 2)). The inner call f(x + 2) is computed first, and its result becomes the argument of the outer call. For any x < 12 the result is 11, but the number of calls grows the smaller x is. It is a good exercise in tracing the stack: the value and the total number of calls are printed.

Complexitate
O(12 - x) apeluri pentru x < 12, O(1) altfel
Clasa
Clasa a X-a (Grade 10)

Exemple

Exemplul 1

Intrare

8

Ieșire așteptată

11 9
Exemplul 2

Intrare

15

Ieșire așteptată

14 1

Codul C++

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

functia-manna-pnueli.cpp
/*
 * Titlu: Funcția Manna-Pnueli
 * Clasa: 10
 * Capitol: Recursivitate
 * Descriere: Funcția este definită astfel: f(x) = x - 1 dacă x >= 12, altfel
 *            f(x) = f(f(x + 2)). Autoapelul interior f(x + 2) se calculează primul,
 *            iar rezultatul lui devine argumentul autoapelului exterior. Pentru orice
 *            x < 12 rezultatul este 11, dar numărul de apeluri crește cu cât x este
 *            mai mic. Este un exercițiu bun de urmărire a stivei: se afișează valoarea
 *            și numărul total de apeluri.
 * Complexitate: O(12 - x) apeluri pentru x < 12, O(1) altfel
 *
 * Exemplu
 * Intrare: 8
 * Ieșire: 11 9
 *
 * Exemplu
 * Intrare: 15
 * Ieșire: 14 1
 */
#include <iostream>
using namespace std;

int apeluri;

int f(int x)
{
    apeluri++;
    if (x >= 12)
        return x - 1;
    return f(f(x + 2));
}

int main()
{
    int x;
    cin >> x;
    int rez = f(x);
    cout << rez << ' ' << 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.