Cod sursa(job #793239)

Utilizator toranagahVlad Badelita toranagah Data 2 octombrie 2012 13:09:09
Problema Bool Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.41 kb
#include <fstream>
#include <iostream>
#include <cctype>
#include <cassert>
using namespace std;

ifstream fin("apel.in");
ofstream fout("apel.out");
string s, func;

char qu[27][251];
int qu_back[27];
char st[251];
int stTop = 0;
int ev[251];
int evTop = 0;
int var[27];
int val[27][27];


void shunting_yard(int pos);
int eval(string& exp);

int main(int argc, char const *argv[])
{
    getline(fin, s);
    int l = s.size();
    do {
        getline(fin, func);
        if (islower(func[0])) {
            for (unsigned int i = 2; i < func.size(); ++i) {
                if (isdigit(func[i])) {
                    var[func[0]-'a'] = var[func[0]-'a'] * 10 + func[i] - '0';
                }
            } 
        }
    } while (islower(func[0]));
    
    do {
        unsigned int i;
        for (i = 0; i < func.size() && func[i] != '='; ++i);
        shunting_yard(i+1);
        getline(fin, func);
    } while (!fin.eof());
    fout << eval(s);
    return 0;
}

void shunting_yard(int pos) {
    for (unsigned int i = pos; i < func.size(); ++i) {
        if (isalnum(func[i])) {
            qu[func[0]-'A'][++qu_back[func[0]-'A']] = func[i];
        } else if (func[i] == '(') {
            st[++stTop] = '(';
        } else if (func[i] == ')') {
            while (stTop > 0 && st[stTop] != '(') {
                qu[func[0]-'A'][++qu_back[func[0]-'A']] = st[stTop];
                --stTop;
            }
            --stTop;
        } else if (func[i] == '+' || func[i] == '-') {
            while (stTop > 0 && st[stTop] != '(') {
                qu[func[0]-'A'][++qu_back[func[0]-'A']] = st[stTop];
                --stTop;
            }
            st[++stTop] = func[i];
        } else if (func[i] == '*') {
            while (stTop > 0 && st[stTop] == '*') {
                qu[func[0]-'A'][++qu_back[func[0]-'A']] = st[stTop];
                --stTop;
            }
            st[++stTop] = func[i];
        }
    }
    while (stTop > 0) {
        qu[func[0]-'A'][++qu_back[func[0]-'A']] = st[stTop];
        --stTop;        
    }
}

int eval(string& exp) {
    assert(isupper(exp[0]));
    char name = exp[0];
    int valExp = 0, level = 0;
    string f;
    for (int i = 2; i < exp.size() - 1; ++i) {
        if (isdigit(exp[i])) {
            val[name-'A'][valExp] = exp[i] - '0';
            ++valExp;
        } else if (islower(exp[i])) {
            val[name-'A'][valExp] = var[exp[i]-'a'];
            ++valExp;
        } else if (isupper(exp[i])) {
            int temp = i;
            while (exp[i] != ')' || level > 0) {
                ++i;
                if (exp[i] == '(') ++level;
                if (exp[i] == ')' && level > 0) --level;
            }
            f = exp.substr(temp, i-temp+1);
            val[name-'A'][valExp] = eval(f);
            ++valExp;
        } 
    }

    for (unsigned int i = 1; i <= qu_back[name-'A']; ++i) {
        if (isdigit(qu[name-'A'][i])) {
            ev[++evTop] = qu[name-'A'][i] - '0';
        } else if (islower(qu[name-'A'][i])) {
            ev[++evTop] = val[name-'A'][qu[name-'A'][i]-'a'];
        } else if (qu[name-'A'][i] == '+') {
            ev[evTop-1] += ev[evTop];
            --evTop;
        } else if (qu[name-'A'][i] == '-') {
            ev[evTop-1] -= ev[evTop];
            --evTop;
        } else if (qu[name-'A'][i] == '*') {
            ev[evTop-1] *= ev[evTop];
            --evTop;
        }
    }
    assert(evTop == 1);
    int result = ev[evTop];
    --evTop;
    return result;
}