Cod sursa(job #626958)

Utilizator igsifvevc avb igsi Data 28 octombrie 2011 17:59:36
Problema Evaluarea unei expresii Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.13 kb
#include <fstream>
#include<string.h>

using namespace std;

#define MAX 100002
#define IN "evaluare.in"
#define OUT "evaluare.out"

struct ListaOp{char op;ListaOp *urm;} *listaOp;
int nrOp;
struct ListaT{long t;ListaT *urm;} *listaT;
int nrT;
char expresie[MAX];

void pushOp(char op);
void pushT(long t);
char popOp();
long popT();
int comparator(char op1, char op2);
long evaluare();
long operatie(long a, char op, long b);
void f1();
void f2(char op);
void f3(char op);

int main()
{
    ifstream fin(IN);
    fin.getline(expresie,100001);
    ofstream fout(OUT);
    fout<< evaluare();
    fout.close();
    return 0;
}

long evaluare()
{
    int l = strlen(expresie);
    int i = 0, nr = 0;
    char c;
    while(i < l)
    {
        c = expresie[i];
        switch(c)
        {
            case '(': pushOp(c);i++;break;
            case ')': f1();i++;break;
            case '+':
            case '-': f2(c);i++;break;
            case '*':
            case '/': f3(c);i++;break;
            default:
                nr = nr*10 + (c - '0');
                i++;
                while(i < l && '0'<=expresie[i] && expresie[i]<='9')
                {
                    nr = nr*10 + (expresie[i]-'0');
                    i++;
                }
                pushT(nr);
                nr = 0;
        }
    }
    long a, b;
    char o;
    while(nrOp)
    {
        b = popT();
        a = popT();
        o = popOp();
        a = operatie(a, o, b);
        pushT(a);
    }
    return popT();
}
void f3(char op)
{
    long a,b;
    char o;
    while(nrOp && (listaOp->op == '*' || listaOp->op == '/'))
    {
        b = popT();
        a = popT();
        o = popOp();
        a = operatie(a, o, b);
        pushT(a);
    }
    pushOp(op);
}
void f2(char op)
{
    long a,b;
    char o;
    while(nrOp && listaOp->op!='(')
    {
        b = popT();
        a = popT();
        o = popOp();
        a = operatie(a, o, b);
        pushT(a);
    }
    pushOp(op);
}
void f1()
{
    long a,b;
    char op;
    while(listaOp->op!='(')
    {
        b = popT();
        a = popT();
        op = popOp();
        a = operatie(a, op, b);
        pushT(a);
    }
    popOp();
}
long operatie(long a, char op, long b)
{
    long rez;
    switch(op)
    {
        case '+': rez = a+b;break;
        case '-': rez = a-b;break;
        case '*': rez = a*b;break;
        case '/': rez = a/b;break;
    }
    return rez;
}
void pushOp(char op)
{
    nrOp++;
    ListaOp *c = new ListaOp;
    c->op = op;
    c->urm = listaOp;
    listaOp = c;
}
void pushT(long t)
{
    nrT++;
    ListaT *c = new ListaT;
    c->t = t;
    c->urm = listaT;
    listaT = c;
}
char popOp()
{
    nrOp--;
    char op = listaOp->op;
    listaOp = listaOp->urm;
    return op;
}
long popT()
{
    nrT--;
    long rez = listaT->t;
    listaT = listaT->urm;
    return rez;
}
int comparator(char op1, char op2)
{
    if(op1 == '(' && op2 == ')')    return 1;
    if((op1 == '+' || op1 == '-') && (op2 != '(' && op2 != ')')) return 2;
    if((op1 == '*' || op1 == '/') && (op2 == '*' || op2 == '/')) return 2;
    if((op1 == '*' || op1 == '/') && (op2 == '+' || op2 == '-')) return 3;
    if(op2 == ')') return 4;
    return 0;
}