Cod sursa(job #2094789)

Utilizator AcuasPopescu Nicolae-Aurelian Acuas Data 26 decembrie 2017 15:59:03
Problema Evaluarea unei expresii Scor 100
Compilator c Status done
Runda Arhiva educationala Marime 3.72 kb
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

struct stack{
    int operand;
    char key;
    struct stack * next;
};

struct stack * push(struct stack * ST, char x, int a) {
    struct stack * elem = (struct stack *) malloc(sizeof(struct stack *));
    if(elem == NULL) {
        printf("OVERFLOW.");
        exit(EXIT_FAILURE);
    }
    elem->key = x;
    elem->operand = a;
    elem->next = ST;
    ST = elem;
    return ST;
}

struct stack * pop(struct stack * ST) {
    if(ST == NULL) {
        printf("UNDERFLOW.");
        exit(EXIT_FAILURE);
    }
    struct stack * forDelete = ST;
    ST = ST->next;
    free(forDelete);
    return ST;
}

struct stack * peek(struct stack * ST) {
    if(ST != NULL) {
        return ST;
    }
}

int isEmpty(struct stack * ST) {
    if(ST == NULL)
        return 1;
    return 0;
}

int isOperator(char x) {
    return x == '+' || x == '-' || x == '/' || x == '*' || x == '%';
}

int Prec(char ch)
{
    switch (ch)
    {
        case '+':
        case '-':
            return 1;

        case '*':
        case '/':
        case '%':
            return 2;
    }
    return -1;
}
int main(){
    struct stack * ST = NULL;
    FILE * fout = fopen("evaluare.out", "wt");
    FILE * fin = fopen("evaluare.in", "rt");
    char * sir = (char *) calloc(100001, sizeof(char));
    fgets(sir, 100000, fin);
    char * myString = (char *) calloc(300001, sizeof(char));
    sir[strlen(sir) - 1] = '\0';
    int n = strlen(sir), i, m = 0;
    for(i = 0; i < n; ++i) {
        if(isdigit(sir[i])){
            while(isdigit(sir[i])){
                myString[m++] = sir[i];
                ++i;
            }
            myString[m++] = ' ';
            --i;
        }
        else if(isOperator(sir[i])) {
            if(isEmpty(ST)) {
                ST = push(ST, sir[i], 0);
            }
            else {
                if(Prec(peek(ST)->key) < Prec(sir[i]))
                    ST = push(ST, sir[i], 0);
                else {
                    while(!isEmpty(ST) && Prec(peek(ST)->key) >= Prec(sir[i])) {
                        myString[m++] = peek(ST)->key;
                        myString[m++] = ' ';
                        ST = pop(ST);
                    }
                    ST = push(ST, sir[i], 0);
                }
            }
        }
        else if(sir[i] == '(') {
            ST = push(ST, sir[i], 0);
        }
        else if(sir[i] == ')') {
            while(!isEmpty(ST) && peek(ST)->key != '('){
                myString[m++] = peek(ST)->key;
                myString[m++] = ' ';
                ST = pop(ST);
            }
            ST = pop(ST);

        }
    }
    while(!isEmpty(ST)) {
        myString[m++] = peek(ST)->key;
        myString[m++] = ' ';
        ST = pop(ST);
    }
    myString[m] = '\0';
    free(sir);
    n = strlen(myString);
    int a, b;
    for(i = 0; i < n; ++i) {
        if(isdigit(myString[i])) {
            m = 0;
            while(i < n && isdigit(myString[i])){
                m = m * 10 + myString[i] - '0';
                ++i;
            }
            --i;
            ST = push(ST, 0, m);
        }
        else if(isOperator(myString[i])) {
            b = peek(ST)->operand;
            ST = pop(ST);
            a = peek(ST)->operand;
            ST = pop(ST);
            switch(myString[i]) {
                case '+' : ST = push(ST, 0, a + b); break;
                case '-' : ST = push(ST, 0, a - b); break;
                case '*' : ST = push(ST, 0, a * b); break;
                case '/' : ST = push(ST, 0, a / b); break;
                case '%' : ST = push(ST, 0, a % b); break;
            }
            //printf("%d \n", ST->operand);
        }
    }
    fprintf(fout,"%d", ST->operand);
    fclose(fin);
    fclose(fout);
    return 0;
}