Cod sursa(job #2925337)

Utilizator ILikeitN Stef ILikeit Data 14 octombrie 2022 18:28:02
Problema Evaluarea unei expresii Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.11 kb
#include <bits/stdc++.h>
using namespace std;

ifstream f("evaluare.in");
ofstream g("evaluare.out");
#define cin f
#define cout g

map<char, int> priority = {
    { '*', 2 },
    { '/', 2 },
    { '+', 1 },
    { '-', 1 },
};

struct Node {
    char op;
    int val;
    Node *st, *dr;
    Node(char c = 0, int v = 0, Node* s = 0, Node* d = 0) :
        op(c), val(v), st(s), dr(d) {};
};

struct ParseResult {
    string result;
    int index;
    friend ostream& operator<< (ostream& os, const ParseResult& p) { return os << p.result << ' ' << p.index; }
    ParseResult(string r = "", int i = 0) :
        result(r), index(i) {};
} mainParser(string, int);

int evaluate(int left, char op, int right) {
    switch (op) {
    case '*': return left * right;
    case '/': return left / right;
    case '+': return left + right;
    case '-': return left - right;
    default: throw runtime_error("You stink");
    };
    return 0;
}

ParseResult numberParser(string s, int i) {
    string result = "";
    while (s[i] && isdigit(s[i])) result += s[i++];
    return ParseResult(result, i);
}

ParseResult betweenParser(string s, const char delim[2], int i) {
    auto updateState = [&](char c) {
        if (c == delim[0]) return 1;
        else if (c == delim[1]) return -1;
        else return 0;
    };
    int state = 0;
    string result = "";
    do {
        state += updateState(s[i]);
        result += s[i++];
    } while (s[i] && state != 0);

    result.erase(result.begin());
    result.erase(result.end() - 1);

    return ParseResult(result, i);
}

ParseResult mainParser(string s, int i) {
    stack<char> operators;
    stack<char> operands;
    int result = 0;

    while (s[i]) {
        if (isspace(s[i])) {
            i++;
            continue;
        }
        else if (isdigit(s[i])) {
            auto _ = numberParser(s, i);
            operands.push(stoi(_.result));
            i = _.index;
        }
        else if (s[i] == '(') {
            auto _ = betweenParser(s, "()", i);
            operands.push(stoi(mainParser(_.result, 0).result));
            i = _.index;
        }
        else /* is operator */ {
            char op = s[i];
            if (operators.empty() || priority[op] >= priority[operators.top()])
                operators.push(op);
            else {
                int right = operands.top(); operands.pop();
                int left = operands.top(); operands.pop();
                operands.push(evaluate(left, operators.top(), right));
                operators.pop();
                operators.push(op);
            }
            i++;
        }
    }

    while (!operators.empty()) {
        char op = operators.top(); operators.pop();
        int right = operands.top(); operands.pop();
        int left = operands.top(); operands.pop();
        operands.push(evaluate(left, op, right));
    }

    if (operands.empty()) throw runtime_error("You stink");
    return ParseResult(to_string(operands.top()), i);
}

int main()
{
    string s; cin >> s;
    cout << mainParser(s, 0).result;

    return 0;
}