Cod sursa(job #2512207)

Utilizator hunting_dogIrimia Alex hunting_dog Data 20 decembrie 2019 18:37:36
Problema Evaluarea unei expresii Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 5.16 kb
#include <iostream>
#include <fstream>
#include <stack>
#include <queue>

#define NMAX 1000

using namespace std;


ifstream fin("apel.in");
ofstream fout("apel.out");

class Function
{
private:
    unsigned short params_no=0;
    long values[26]={0};
    char params[10];
    queue <pair <char,long>> q;

    char priorities[100]={0};
    char arity[100]={0};

    bool isVar(char c)
    {
        return (c>='a' && c<='z');
    }

    void getParams(char *&p)
    {
        while(*p!=')')
        {
            if(isVar(*p))
                params[params_no++]=*p;
            ++p;
        }
        p+=2;
    }

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

    long getNumber(char *&p)
    {
        long res=0;
        while(isNumber(*p))
        {
            res=res*10+(*p-'0');
            ++p;
        }
        --p;
        return res;
    }

    void buildPostfix(char *&p)
    {
        stack <long> s;
        while(*p!='\0')
        {
            if(isNumber(*p))
            {
                q.push(make_pair(0,getNumber(p)));
            }
            else if(isVar(*p))
            {
                q.push(make_pair(1,*p));
            }
            else if(*p=='(')
                s.push(*p);
            else if(*p==')')
            {
                while(s.top()!='(')
                {
                    q.push(make_pair(3,s.top()));
                    s.pop();
                }
                s.pop();
            }
            else
            {
                if(*p=='-' && !isNumber(*(p-1)) && !isVar(*(p-1)))
                    *p='~';
                while(!s.empty() && priorities[s.top()]>=priorities[*p] && s.top()!=*p)
                {
                    q.push(make_pair(3,s.top()));
                    s.pop();
                }
                s.push(*p);
            }
            ++p;
        }

        while(!s.empty())
        {
            q.push(make_pair(3,s.top()));
            s.pop();
        }
}

long getRes(long *x,char op)
{
    switch(op)
    {
    case '+':
        return x[0]+x[1];
    case '-':
        return x[1]-x[0];
    case '*':
        return x[0]*x[1];
    case '/':
        return x[1]/x[0];
    case '~':
        return -x[0];
    }
}

long evaluate()
{
    queue <pair <char,long>> e=q;
    stack <long> s;
    while(!e.empty())
    {
        if(e.front().first==0)
            s.push(e.front().second);
        else if(e.front().first==1)
            s.push(values[e.front().second-'a']);
        else
        {
            int a=arity[e.front().second];
            long x[2],k=0;
            while(a--)
            {
                x[k++]=s.top();
                s.pop();
            }
            s.push(getRes(x,e.front().second));
        }
        e.pop();
    }

    return s.top();
}

public:
    Function()
    {

    }

    Function(char *func_def)
    {
        char *p=func_def;
        getParams(p);

        priorities['+']=1;
        priorities['-']=1;
        priorities['*']=2;
        priorities['/']=2;
        priorities['~']=3;

        arity['+']=2;
        arity['-']=2;
        arity['*']=2;
        arity['/']=2;
        arity['~']=1;

        buildPostfix(p);
    }

    void printPostfix()
    {
        queue <pair <char,long>> e=q;
        while(!e.empty())
        {
            if(e.front().first==0)
                cout<<e.front().second<<' ';
            else
                cout<<(char)e.front().second<<' ';
            e.pop();
        }
        cout<<'\n';
    }

    long get(long *param_list)
    {
        for(int i=0;i<params_no;++i)
        {
            values[params[i]-'a']=param_list[i];
        }

        return evaluate();
    }
};

bool isVar(char c)
{
    return (c>='a' && c<='z');
}

bool isFunc(char c)
{
    return (c>='A' && c<='Z');
}

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

long getNumber(char *&p)
{
    long res=0;
    while(isNumber(*p))
    {
        res=res*10+(*p-'0');
        ++p;
    }
    --p;

    return res;
}

long values[26]={0};

long eval(char *&p,Function *f)
{
    Function fun=f[*p-'A'];
    ++p;
    long params[10],k=0;
    while(*p!=')')
    {
        if(isNumber(*p) || *p=='-')
        {
            if(*p=='-')
                params[k++]=-getNumber(++p);
            else
                params[k++]=getNumber(p);
        }
        else if(isVar(*p))
            {
                params[k++]=values[*p-'a'];
            }
        else if(isFunc(*p))
            params[k++]=eval(p,f);
        ++p;
    }

    return fun.get(params);
}

int main()
{

    char v[NMAX];
    fin.get(v,NMAX);

    Function f[NMAX];

    while(1)
    {
        char s[NMAX];
        if(!(fin>>s))
            break;
        char *c=s;
        if(isVar(*c))
            {
                c+=2;
                values[*(c-2)-'a']=getNumber(c);

            }
        else if(isFunc(*c))
        {
            f[*c-'A']=Function(s);
        }
    }

    char *p=v;

    fout<<eval(p,f);


    return 0;
}