Cod sursa(job #632235)

Utilizator vlcmodanModan Valentin vlcmodan Data 10 noiembrie 2011 17:20:49
Problema Evaluarea unei expresii Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2 kb
#include <stdio.h>

#define N 100001

char e[N];
int i;

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

int main(void) {

    freopen("evaluare.in", "r", stdin); 
	freopen("evaluare.out", "w", stdout);
	fgets(e, 100001, 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;
}