Cod sursa(job #630821)

Utilizator caen1c a e n caen1 Data 6 noiembrie 2011 16:53:46
Problema Evaluarea unei expresii Scor 100
Compilator c Status done
Runda Arhiva educationala Marime 1.94 kb
#include <stdio.h>

#define IN "evaluare.in"
#define OUT "evaluare.out"
#define N 100001

char e[N];
int i;

long factor(void);
long termen(void);
long expresie(void);

int main(void) {

    freopen(IN, "r", stdin); freopen(OUT, "w", stdout);

    fgets(e, N, stdin);

    printf("%ld\n", expresie());

    return 0;
}

// Evaluam un factor. Un factor poate fi:
//      A: un numar natural
//      B: o subexpresie (aflata intre paranteze)
long factor(void) {

    long f = 0; // Aici retinem factorul

    if(e[i] >= '0' && e[i] <= '9') // Caz A: factorul este un numar natural
        while(e[i] >= '0' && e[i] <= '9')
            f = f * 10 + e[i++] - '0'; // Calculam factorul
    else if(e[i] == '(') { // Caz B: factorul este o subexpresie

        ++i; // Sarim paranteza
        f = expresie(); // Evaluam subexpresia (recursivitate indirecta)
        ++i; // Sarim paranteza inchisa
    }

    return f;
}

// Evaluam un termen. Un termen este un numar natural format din inmultirea
// sau impartirea a doi factori
long termen(void) {

    long t = factor(); // Luam primul factor

    // Cat timp avem inmultire sau impartire, calculam rezultatul
    while(e[i] == '*' || e[i] == '/') { 

        if(e[i] == '*') {

            ++i; // Sarim operatorul
            t *= factor(); // Luam urmatorul factor
        } else {

            ++i; // Sarim operatorul
            t /= factor(); // Luam urmatorul factor
        }
    }

    return t;
}

// Evaluam o expresie. O expresie este un numar natural format din adunarea
// sau scaderea a doi termeni
long expresie(void) {

    long r = termen(); // Luam primul termen

    // Cat timp avem adunare sau scadere, calculam rezultatul
    while(e[i] == '+' || e[i] == '-') {

        if(e[i] == '+') {

            ++i; // Sarim operatorul
            r += termen(); // Luam urmatorul termen
        } else {

            ++i; // Sarim operatorul
            r -= termen(); // Luam urmatorul termen
        }
    }

    return r;
}