Cod sursa(job #2329239)

Utilizator igsifvevc avb igsi Data 26 ianuarie 2019 15:08:14
Problema Evaluarea unei expresii Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.08 kb
#include <cctype>
#include <fstream>
#include <map>
#include <stack>
#include <string>

long eval(const std::string &exp);

int main()
{
    std::ifstream fin("evaluare.in");
    std::ofstream fout("evaluare.out");

    std::string expression;
    fin >> expression;

    fout << eval(expression) << std::endl;

    return 0;
}

long parse_number(std::string::const_iterator &c)
{
    long number = 0;

    while (std::isdigit(*c))
    {
        number = number * 10 + (*c - '0');
        c++;
    }

    return number;
}

void do_binary_op(std::stack<long> &values, std::stack<char> &operators)
{
    long op1, op2;
    op2 = values.top();
    values.pop();
    op1 = values.top();
    values.pop();

    char op = operators.top();
    operators.pop();

    long result = 0;
    switch (op)
    {
    case '+':
        result = op1 + op2;
        break;
    case '-':
        result = op1 - op2;
        break;
    case '*':
        result = op1 * op2;
        break;
    case '/':
        result = op1 / op2;
        break;
    };

    values.push(result);
}

long eval(const std::string &exp)
{
    std::stack<long> values;
    std::stack<char> operators;

    std::map<char, int> precedence = {{'(', -1}, {'+', 0}, {'-', 0}, {'*', 1}, {'/', 1}};

    for (std::string::const_iterator c = exp.cbegin(); c != exp.cend();)
    {
        if (std::isdigit(*c))
        {
            values.push(parse_number(c));
        }
        else if (*c == '(')
        {
            operators.push(*c);
            c++;
        }
        else if (*c == ')')
        {
            while (operators.top() != '(')
            {
                do_binary_op(values, operators);
            }

            operators.pop();
            c++;
        }
        else // c is a binary operator
        {
            while (!operators.empty() && precedence[operators.top()] >= precedence[*c])
            {
                do_binary_op(values, operators);
            }

            operators.push(*c);
            c++;
        }
    }

    while (!operators.empty())
    {
        do_binary_op(values, operators);
    }

    return values.top();
}