Cod sursa(job #495720)

Utilizator marius21Marius Petcu marius21 Data 26 octombrie 2010 17:43:17
Problema Evaluarea unei expresii Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.23 kb
#include <cstdio>
#include <cstdlib>
#include <list>

using namespace std;

FILE *fin=fopen("evaluare.in","r");
FILE *fout=fopen("evaluare.out","w");

enum kOperands {
    kNull = 0,
    kRightPar,
    kPlus,
    kMinus,
    kMult,
    kDiv,
    kLeftPar
};

enum kTypes {
    kTypeOperand = 0,
    kTypeOperator
};

struct el
{
    int type,value;
}; 
el a[100000];
int n = 0;

inline bool iscifra(char c)
{
    return (c>='0')&&(c<='9');
}

inline int order(int op)
{
    switch(op)
    {
        case kNull:
            return -1;
        case kRightPar:
            return 0;
        case kPlus:
            return 1;
        case kMinus:
            return 1;
        case kMult:
            return 2;
        case kDiv:
            return 2;
        case kLeftPar:
            return 1000;
        default:
            return 1;
    }
}

inline int opFromChar(char c)
{
    switch (c)
    {
        case '(':
            return kLeftPar;
        case ')':
            return kRightPar;
        case '+':
            return kPlus;
        case '-':
            return kMinus;
        case '*':
            return kMult;
        case '/':
            return kDiv;
        default:
            //return kNull;
             exit(-2);
    }
}

void process_operand(int nr)
{
    a[n].type=kTypeOperand;
    a[n].value = nr;
    n++;
}

list<int> stack;

void process_operator(int nr)
{
    int crr;
    while (!(stack.empty())&&(order(crr=stack.back())>=order(nr)))
    {
        if (crr!=kLeftPar)
        {
            a[n].type=kTypeOperator;
            a[n].value=crr;
            n++;
            stack.pop_back();
        } else {
            if (nr==kRightPar)
                stack.pop_back();
            break;
        }
    }
    if ((nr!=kRightPar)&&(nr!=kNull))
    {
        stack.push_back(nr);
    }
}

int solve(int a, int b, int op)
{
    switch(op)
    {
        case kPlus:
            return a+b;
        case kMinus:
            return a-b;
        case kMult:
            return a*b;
        case kDiv:
            return a/b;
        default:
            //return 0; 
            exit(-1);
    }
}

int solve_polonese()
{
    for (int i=0; i<n ;i++)
    {
        if (a[i].type==kTypeOperand)
        {
            stack.push_back(a[i].value);
        }
        else
        {
            int ond2 = stack.back();
            stack.pop_back();
            int ond1 = stack.back();
            stack.pop_back();
            int res = solve(ond1,ond2,a[i].value);
            stack.push_back(res);
        }
    }
    return stack.back();
}

int main (int argc, char * const argv[]) {
    char c;
    int nr = 0;
    int hasnr = 0;
    while ((c=fgetc(fin))!=EOF)
    {
        if (c==' ') continue;
        if (c=='\n') continue;
        if (c=='\r') continue;
        if (iscifra(c))
        {
            hasnr = 1;
            nr=nr*10+c-'0';
        }
        else
        {
            if (hasnr)
                process_operand(nr);
            hasnr = 0;
            nr = 0;
            process_operator(opFromChar(c));
        }
    }
    if (hasnr)
    	process_operand(nr);
    process_operator(kNull);
    //for (int i=0; i<n; i++)
    //    printf("%d %d\n",a[i].type,a[i].value);
    fprintf(fout,"%d\n",solve_polonese());
    fclose(fin);
    fclose(fout);
    return 0;
}