Cod sursa(job #1854523)

Utilizator AurelGabrielAurel Gabriel AurelGabriel Data 22 ianuarie 2017 20:13:36
Problema Evaluarea unei expresii Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 3.29 kb
#include <fstream>
#include <stack>
#include <cstring>

using namespace std;

#define PLUS -1
#define MINUS -2
#define MULTIPLY -4
#define DIVIDE -5
#define LPARENTHESIS -8

inline bool isOperator(const char& c)
{
    if(c == '+' || c == '-' || c == '*' || c == '/')
        return true;
    return false;
}

inline bool isOperatorI(const long int& i)
{
    if(i == PLUS || i == MINUS || i == MULTIPLY || i == DIVIDE)
        return true;
    return false;
}

inline long int cti(const char& c)
{
    return c - '0';
}

inline long int pharseVal(char* s, unsigned long int& i)
{
    long int n = cti(s[i]);
    while(s[i+1] >= '0' && s[i+1] <= '9'  && i+1 < strlen(s))
    {
        i++;
        n = n*10 + cti(s[i]);
    }
    return n;
}

inline long int opti(const char& c)
{
    if(c == '+')
        return PLUS;
    else
    if(c == '-')
        return MINUS;
    else
    if(c == '*')
        return MULTIPLY;
    else
    if(c == '/')
        return DIVIDE;
    else
    if(c == '(')
       return LPARENTHESIS;
    return -10;
}

inline long int applyOp(long int a, long int b, long int op)
{
    switch(op)
    {
        case PLUS:
            return a+b;
        case MINUS:
            return a-b;
        case MULTIPLY:
            return a*b;
        case DIVIDE:
            return a/b;
    }
    return 0;
}

inline bool gradeTest(long int op1, long int op2)
{
    if ((op1 == MULTIPLY || op1 == DIVIDE) && (op2 == PLUS || op2 == MINUS))
        return false;
    return true;
}

int eval(char* s)
{
    stack<int> val;
    stack<int> op;

    unsigned long int i = 0;
    while(i < strlen(s))
    {
        if(s[i] >= '0' && s[i] <= '9')
        {
            long int n = pharseVal(s,i);
            val.push(n);
        }
        else
        if(s[i] == '(')
        {
            op.push(opti(s[i]));
        }
        else
        if(s[i] == ')')
        {
                long int v;
                while(op.top() != LPARENTHESIS)
                {
                    long int a = val.top();
                    val.pop();
                    long int b = val.top();
                    val.pop();
                    v = applyOp(b, a, op.top());
                    op.pop();
                    val.push(v);
                }
                op.pop();
        }
        else
        if(isOperator(s[i]))
        {
            if(op.size() > 0 && isOperatorI(op.top()))
            {
                while(!op.empty() && gradeTest(opti(s[i]), op.top()))
                {
                    long int a = val.top();
                    val.pop();
                    long int b = val.top();
                    val.pop();
                    val.push(applyOp(b, a, op.top()));
                    op.pop();
                }
            }
            op.push(opti(s[i]));
        }
        i++;
    }

    while(!op.empty())
    {
        long int a = val.top();
        val.pop();
        long int b = val.top();
        val.pop();
        val.push(applyOp(b, a, op.top()));
        op.pop();
    }
    return val.top();
}

char s[100000];

int main()
{
    ifstream f("evaluare.in");
    ofstream g("evaluare.out");

    f.get(s, 100000);

    g << eval(s);

    return 0;
}