Cod sursa(job #3301888)

Utilizator BucsMateMate Bucs BucsMate Data 30 iunie 2025 22:47:36
Problema Evaluarea unei expresii Scor 60
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 5.58 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <stack>
#include <cstring>
#include <cctype>
#include <queue>
#include <cmath>

using namespace std;

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

const int OPERATOR = 1, CONSTANT = 2, VARIABLE = 3, FUNCTION = 4;

class Node{
public:
    int type;
    float value;
    bool isConstant;
    string str;
    Node *left = nullptr, *right = nullptr;

    Node(int type, float value, bool isConstant, string str) {
        this->type = type;
        this->value = value;
        this->isConstant = isConstant;
        this->str = str;
    }
    Node(const Node &n) {
        this->type = n.type;
        this->value = n.value;
        this->isConstant = n.isConstant;
        this->str = n.str;
    }
    ~Node() {
        cout << "torolve\n";
        delete left;
        delete right;
    }
};

int precedence(string &operation)
{
    if(operation == "+" || operation == "-"){
        return 1;
    }
    if(operation == "*" || operation == "/"){
        return 2;
    }
    return 0;
}

struct Token
{
    int type;
    float value = 0;
    string str;
};

Token createNextToken(int &pos, string &expr)
{
    Token result;
    if(strchr("+-*/()", expr[pos]) != nullptr){
        result.type = OPERATOR;
        result.value = 0;
        result.str = expr[pos];
        pos++;
    }
    else if(isdigit(expr[pos])){
        result.type = CONSTANT;
        float num = 0;
        while(isdigit(expr[pos])){
            num = 10*num + (expr[pos] - '0');
            pos++;
        }
        result.value = num;
    }
    else{
        if(isalpha(expr[pos]) && isalpha(expr[pos+1])){
            result.type = FUNCTION;
            while(isalpha(expr[pos])){
                result.str = result.str + expr[pos];
                pos++;
            }
        }
        else if(isalpha(expr[pos])){
            result.type = VARIABLE;
            result.str = expr[pos];
            pos++;
        }
    }
    return result;
}

float evaluateOperation(string op, float val1, float val2)
{
    if(op == "sin"){
        return sin(val1);
    } else if(op == "cos"){
        return cos(val1);
    } else if(op == "tan"){
        return tan(val1);
    } else if(op == "+"){
        return val2 + val1;
    } else if(op == "-"){
        return val2 - val1;
    } else if(op == "*"){
        return val2 * val1;
    } else if(op == "/"){
        return (int)(val2 / val1);
    } else{
        return 0;
    }
}

int main()
{
    string expr;
    getline(fin, expr);
    stack<Node*> stNode;
    queue<Token> outputQueue;
    stack<Token> opStack;

    int pos = 0;
    while(pos < expr.size()){
        Token nextToken = createNextToken(pos, expr);

        if(nextToken.type == CONSTANT || nextToken.type == VARIABLE){
            outputQueue.push(nextToken);
        }
        else if(nextToken.type == FUNCTION){
            opStack.push(nextToken);
        }
        else if(nextToken.type == OPERATOR){
            if(nextToken.str == "("){
                opStack.push(nextToken);
            }
            else if(nextToken.str == ")"){
                while(opStack.top().str != "("){
                    outputQueue.push(opStack.top());
                    opStack.pop();
                    if(opStack.empty()){
                        cout << "GEBASZ";
                        break;
                    }
                }
                opStack.pop();
                if(!opStack.empty() && opStack.top().type == FUNCTION){
                    outputQueue.push(opStack.top());
                    opStack.pop();
                }
            }
            else{
                while(!opStack.empty() && opStack.top().str != "(" && precedence(opStack.top().str) >= precedence(nextToken.str)){
                    outputQueue.push(opStack.top());
                    opStack.pop();
                }
                opStack.push(nextToken);
            }
        }
    }
    while(!opStack.empty()){
        outputQueue.push(opStack.top());
        opStack.pop();
    }

    while(!outputQueue.empty()){
        if(outputQueue.front().type == CONSTANT){
            Node *temp = new Node(CONSTANT, outputQueue.front().value, true, "");
            stNode.push(temp);
        }
        else if(outputQueue.front().type == VARIABLE){
            Node *temp = new Node(CONSTANT, 0, false, outputQueue.front().str);
            stNode.push(temp);
        }
        else if(outputQueue.front().type == FUNCTION){
            float value = evaluateOperation(outputQueue.front().str, (*stNode.top()).value, 0);
            Node newNode(FUNCTION, value, false, outputQueue.front().str);
            //newNode.left = &(stNode.top());
            newNode.left = new Node(*stNode.top());
            stNode.pop();
            stNode.push(new Node(newNode));
        }
        else{
            Node *node1 = stNode.top();
            stNode.pop();
            Node *node2 = stNode.top();
            stNode.pop();
            float value = evaluateOperation(outputQueue.front().str, node1->value, node2->value);
            Node *newNode = new Node(OPERATOR, value, false, outputQueue.front().str);
            //newNode.left = &(node1);
            //newNode.right = &(node2);
            newNode->left = node1;
            newNode->right = node2;
            stNode.push(newNode);
        }
        outputQueue.pop();
    }
    Node *root = stNode.top();
    stNode.pop();

    fout << root->value << endl;
    return 0;
}