Cod sursa(job #3178282)

Utilizator Mihai145Oprea Mihai Adrian Mihai145 Data 1 decembrie 2023 16:06:10
Problema Evaluarea unei expresii Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.21 kb
#include <fstream>
#include <string>
#include <vector>
#include <cassert>

using namespace std;

ifstream cin("evaluare.in");
ofstream cout("evaluare.out");

int main()
{
    string exp;
    cin >> exp;
    int n = (int)exp.size();

    vector<int> values;
    vector<char> symbols;

    auto perform_operation = [&]()
    {
        char symbol = symbols.back();
        symbols.pop_back();
        int v2 = values.back();
        values.pop_back();
        int v1 = values.back();
        values.pop_back();

        switch (symbol)
        {
        case '+':
            v1 += v2;
            break;
        case '-':
            v1 -= v2;
            break;
        case '*':
            v1 *= v2;
            break;
        case '/':
            v1 /= v2;
            break;
        default:
            break;
        }

        values.push_back(v1);
    };

    auto precedence = [](char c)
    {
        if (c == '+' || c == '-')
            return 0;
        if (c == '*' || c == '/')
            return 1;
        if (c == '(')
            return -1;

        assert(false);
    };

    for (int i = 0; i < n; i++)
    {
        if (isdigit(exp[i]))
        {
            int number = 0;
            while (i < n && isdigit(exp[i]))
            {
                number = number * 10 + (exp[i] - '0');
                i++;
            }

            values.push_back(number);
            i--; // overshoot by one, the for loop increments as well
        }
        else
        {
            if (exp[i] == '(')
            {
                symbols.push_back(exp[i]);
            }
            else if (exp[i] == ')')
            {
                while (symbols.back() != '(')
                    perform_operation();
                symbols.pop_back();
            }
            else
            {
                // Stop if we encounter '(' (has lowest precedence)
                // Or if we have a + or - and we encounter a * or /
                while (symbols.size() > 0 && precedence(exp[i]) <= precedence(symbols.back()))
                    perform_operation();

                symbols.push_back(exp[i]);
            }
        }
    }

    while (symbols.size() > 0)
        perform_operation();
    cout << values[0] << '\n';

    return 0;
}