Cod sursa(job #2901945)

Utilizator MagnvsDaniel Constantin Anghel Magnvs Data 14 mai 2022 21:53:21
Problema Evaluarea unei expresii Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.73 kb
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
#include <stack>

class asn{
public:
    virtual int32_t execute( ) {
        return 0;
    };
};
class asn_number : public asn{
public:
    int32_t x;
    int32_t execute( ) {
        return x;
    };
};
class asn_sum : public asn{
public:
    asn *lho, *rho;
    int32_t execute( ) {
        return lho->execute()+rho->execute();
    };
};
class asn_difference : public asn{
public:
    asn *lho, *rho;
    int32_t execute( ) {
        return lho->execute()-rho->execute();
    };
};
class asn_product : public asn{
public:
    asn *lho, *rho;
    int32_t execute( ) {
        return lho->execute()*rho->execute();
    };
};
class asn_quotient : public asn{
public:
    asn *lho, *rho;
    int32_t execute( ) {
        return lho->execute()/rho->execute();
    };
};

bool isnumeric( char x ) {
    return x >= '0' && x <= '9';
}

int32_t intfromstring( std::string &x ) {
    int32_t sol = 0, n = x.size();
    for ( int i = 0; i < n; ++ i ) {
        sol = sol*10+x[i]-'0';
    }
    return sol;
}

std::vector<std::string> t;
std::vector<int32_t> p;
asn* ast( int32_t l, int32_t r ) {
    if ( l > r ) {
        asn_number* sol = new asn_number;
        sol->x = 0;
        return sol;
    } else if ( l == r ) {
        asn_number* sol = new asn_number;
        sol->x = intfromstring(t[l]);
        return sol;
    } else {
        int i = r;
        while ( i >= l && t[i][0] != '+' && t[i][0] != '-' ) {
            if ( t[i][0] == ')' ) {
                i = p[i];
            }
            -- i;
        }
        if ( i >= l ) {
            if ( t[i][0] == '+' ) {
                asn_sum* sol = new asn_sum;
                sol->lho = ast(l, i-1);
                sol->rho = ast(i+1, r);
                return sol;
            } else if ( t[i][0] == '-' ) {
                asn_difference* sol = new asn_difference;
                sol->lho = ast(l, i-1);
                sol->rho = ast(i+1, r);
                return sol;
            }
        }

        i = r;
        while ( i >= l && t[i][0] != '*' && t[i][0] != '/' ) {
            if ( t[i][0] == ')' ) {
                i = p[i];
            }
            -- i;
        }
        if ( i >= l ) {
            if ( t[i][0] == '*' ) {
                asn_product* sol = new asn_product;
                sol->lho = ast(l, i-1);
                sol->rho = ast(i+1, r);
                return sol;
            } else if ( t[i][0] == '/' ) {
                asn_quotient* sol = new asn_quotient;
                sol->lho = ast(l, i-1);
                sol->rho = ast(i+1, r);
                return sol;
            }
        }
        return ast(l+1, r-1);
    }
}

int main( ) {
    std::ifstream fin("evaluare.in");
    std::string s;
    fin >> s;
    fin.close();

    int32_t n = s.size();
    for ( int32_t i = 0; i < n; ++ i ) {
        if ( isnumeric(s[i]) == 1 ) {
            std::string x = "";
            while ( i < n && isnumeric(s[i]) == 1 ) {
                x += s[i];
                ++ i;
            }
            -- i;
            t.push_back(x);
        } else {
            std::string x = "";
            x += s[i];
            t.push_back(std::string(x));
        }
    }

    n = t.size();
    p.resize(n);

    std::stack<int32_t> ps;
    for ( int32_t i = 0; i < n; ++ i ) {
        if ( t[i][0] == '(' ) {
            ps.push(i);
        } else if ( t[i][0] == ')' ) {
            p[i] = ps.top();
            p[ps.top()] = i;
            ps.pop();
        }
    }

    std::ofstream fout("evaluare.out");
    fout << ast(0, n-1)->execute() << "\n";
    fout.close();

    return 0;
}