Cod sursa(job #3276764)

Utilizator BledeaAlexBledea Alexandru BledeaAlex Data 14 februarie 2025 15:36:39
Problema Evaluarea unei expresii Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.39 kb
#include <bits/stdc++.h>

using namespace std;

const int L_MAX = 1e5 + 5;
const int MAX_PRIORITY = 2; /// = nr prioritati, chiar daca prima prioritate este 0 (avem 2 prioritati, "+-" si "*/")
unsigned int pos = 0; /// positia unde am ajuns, variabila globala folosita de functiile recursive
string expr;

vector<vector<char> > operators = {
    {'+', '-'},
    {'*', '/'},
    {'^'} /// nu putem implementa puterea in acest cod deoarece este asociativa la dreapta
          /// adica x ^ y ^ z = x ^ (y ^ z) in ordinea de operare
};

void SetInput(string name)
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);

    (void)!freopen((name + ".in").c_str(), "r", stdin);
    (void)!freopen((name + ".out").c_str(), "w", stdout);
}

int GetPriority(char op)
{
    for(int i = 0, sz = operators.size(); i < sz; i++)
        for(char c : operators[i])
            if(op == c) return i;

    return -1; /// undefined
}

int Calc(int x, int y, char op)
{
    switch(op)
    {
        case '+': return x + y;
        case '-': return x - y;
        case '*': return x * y;
        case '/': return x / y;
    }
    return 0;
}

int EvalFactor();

/// Functie recursiva pt evaluare, in functie de nivelul curent de proritate
int Eval(int priorityLevel)
{
    if(priorityLevel == MAX_PRIORITY) /// Am ajuns la ultimul nivel
        return EvalFactor();

    int result = Eval(priorityLevel + 1); /// evaluam primul operand

    while(pos < expr.size())
    {
        char op = expr[pos];

        if(GetPriority(op) != priorityLevel) /// daca operatorul nu face parte din acest nivel de prioritate ne oprim
            break;

        pos++; /// sarim peste operator

        int nextOperand = Eval(priorityLevel + 1);

        result = Calc(result, nextOperand, op);
    }

    return result;
}

/// Functie pentru a evalua nr. si expresii intre paranteza
int EvalFactor()
{
    int result = 0;
    if(expr[pos] == '(')
    {
        pos++; /// Sarim peste '('
        result = Eval(0);
        pos++; /// Sarim peste ')'
    }
    else
    {
        while(isdigit(expr[pos])) /// construim numarul
        {
            result = result * 10 + (expr[pos] - '0');
            pos++;
        }
    }
    return result;
}

int main()
{
    SetInput("evaluare");

    cin >> expr;
    pos = 0;
    cout << Eval(0) << '\n';

    return 0;
}