Cod sursa(job #3250304)

Utilizator andrei.arnautuAndi Arnautu andrei.arnautu Data 19 octombrie 2024 22:41:03
Problema Evaluarea unei expresii Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.81 kb
/**
  *  Worg
  */
#include <fstream>
#include <string>
#include <cctype>
#include <memory>

class Node {
public:
    virtual int evaluate() = 0;
    virtual ~Node() {}
};

class NumericNode : public Node {
public:
    int value;

    NumericNode(int _value) : value(_value) {}

    int evaluate() override {
        return value;
    }
};

class OperatorNode : public Node {
public:
    char op;
    std::unique_ptr<Node> left;
    std::unique_ptr<Node> right;

    OperatorNode(char _op, std::unique_ptr<Node> _left, std::unique_ptr<Node> _right) :
        op(_op),
        left(std::move(_left)),
        right(std::move(_right))
    {}

    int evaluate() override {
        int left_value = left->evaluate();
        int right_value = right->evaluate();
        switch (op) {
            case '+': return left_value + right_value;
            case '-': return left_value - right_value;
            case '*': return left_value * right_value;
            case '/': return left_value / right_value;
            default: return 0;
        }
    }
};

class ExpressionParser {
private:
    const std::string& expression;
    size_t pos;

    std::unique_ptr<Node> parse_expression() {
        auto node = parse_term();
        while (pos < expression.size() && (expression[pos] == '+' || expression[pos] == '-')) {
            char op = expression[pos++];
            auto right = parse_term();
            node = std::make_unique<OperatorNode>(op, std::move(node), std::move(right));
        }
        return node;
    }

    std::unique_ptr<Node> parse_term() {
        auto node = parse_factor();
        while (pos < expression.size() && (expression[pos] == '*' || expression[pos] == '/')) {
            char op = expression[pos++];
            auto right = parse_factor();
            node = std::make_unique<OperatorNode>(op, std::move(node), std::move(right));
        }
        return node;
    }

    std::unique_ptr<Node> parse_factor() {
        if (expression[pos] == '(') {
            pos++;
            auto node = parse_expression();
            pos++;
            return node;
        } else {
            size_t start = pos;
            while (pos < expression.size() && std::isdigit(expression[pos])) {
                pos++;
            }
            int value = std::stoi(expression.substr(start, pos - start));
            return std::make_unique<NumericNode>(value);
        }
    }

public:
    ExpressionParser(const std::string& s) : expression(s), pos(0) {}

    int parse() {
        return parse_expression()->evaluate();
    }
};


int main() {
    std::ifstream fin("evaluare.in");
    std::ofstream fout("evaluare.out");

    std::string expression;
    fin >> expression;

    ExpressionParser expression_parser(expression);
    int result = expression_parser.parse();
    fout << result << '\n';

    fin.close();
    fout.close();
    return 0;
}