Cod sursa(job #3300215)

Utilizator anamaria-carina.orszariAnamaria-Carina Orszari anamaria-carina.orszari Data 13 iunie 2025 20:53:08
Problema Evaluarea unei expresii Scor 100
Compilator c-64 Status done
Runda Arhiva educationala Marime 2.97 kb
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>

#define MAX_LEN 100005

typedef struct Node {
    int isOperator;
    char op;
    int value;
    struct Node *left, *right;
} Node;

char expr[MAX_LEN];
int pos;

// Creează nod operand
Node* makeValueNode(int val) {
    Node* node = (Node*)malloc(sizeof(Node));
    node->isOperator = 0;
    node->value = val;
    node->left = node->right = NULL;
    return node;
}

// Creează nod operator
Node* makeOpNode(char op, Node* left, Node* right) {
    Node* node = (Node*)malloc(sizeof(Node));
    node->isOperator = 1;
    node->op = op;
    node->left = left;
    node->right = right;
    return node;
}

// Saltă peste spații
void skipSpaces() {
    while (expr[pos] == ' ') pos++;
}

// Citire număr
int readNumber() {
    skipSpaces();
    int val = 0;
    while (isdigit(expr[pos])) {
        val = val * 10 + (expr[pos] - '0');
        pos++;
    }
    return val;
}

// Forward declarations
Node* parseExpression();

// Factor: număr sau paranteză
Node* parseFactor() {
    skipSpaces();
    if (expr[pos] == '(') {
        pos++;
        Node* node = parseExpression();
        skipSpaces();
        pos++; // închide paranteza
        return node;
    } else {
        return makeValueNode(readNumber());
    }
}

// Termen: * sau /
Node* parseTerm() {
    Node* node = parseFactor();
    while (1) {
        skipSpaces();
        if (expr[pos] == '*' || expr[pos] == '/') {
            char op = expr[pos++];
            Node* right = parseFactor();
            node = makeOpNode(op, node, right);
        } else {
            break;
        }
    }
    return node;
}

// Expresie: + sau -
Node* parseExpression() {
    Node* node = parseTerm();
    while (1) {
        skipSpaces();
        if (expr[pos] == '+' || expr[pos] == '-') {
            char op = expr[pos++];
            Node* right = parseTerm();
            node = makeOpNode(op, node, right);
        } else {
            break;
        }
    }
    return node;
}

// Evaluare arbore
int evaluate(Node* node) {
    if (!node->isOperator) return node->value;
    int leftVal = evaluate(node->left);
    int rightVal = evaluate(node->right);
    switch (node->op) {
        case '+': return leftVal + rightVal;
        case '-': return leftVal - rightVal;
        case '*': return leftVal * rightVal;
        case '/': return leftVal / rightVal; // garantat întreg
    }
    return 0; // fallback
}

void freeTree(Node* node) {
    if (!node) return;
    freeTree(node->left);
    freeTree(node->right);
    free(node);
}

int main() {
    FILE* in = fopen("evaluare.in", "r");
    FILE* out = fopen("evaluare.out", "w");

    fgets(expr, MAX_LEN, in);
    pos = 0;

    Node* root = parseExpression();
    int result = evaluate(root);
    fprintf(out, "%d\n", result);

    freeTree(root);
    fclose(in);
    fclose(out);
    return 0;
}