Cod sursa(job #2692129)

Utilizator Silviu45Dinca Silviu Silviu45 Data 31 decembrie 2020 17:57:07
Problema Evaluarea unei expresii Scor 10
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 5.23 kb
/*Evaluarea unei expresii
Se da un sir de caractere ce reprezinta o expresie aritmetica.

Cerinta
Afisati rezultatul obtinut prin evaluarea expresiei.

Date de intrare
Fisierul de intrare evaluare.in va contine pe prima linie un sir de caractere compus din cifre ( '0' - '9' ), operatorii '+', '-', '*', '/' si paranteze( '(', ')' ).

Date de iesire
In fisierul de iesire evaluare.out se va scrie un singur numar intreg care reprezinta valoarea obtinuta in urma evaluarii expresiei.*/

///https://www.dreamincode.net/forums/topic/37428-converting-and-evaluating-infix-postfix-and-prefix-expressions-in-c/
#include <bits/stdc++.h>
#define mod 66600013;
using namespace std;

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

char input[1000],output[2000];
void Read(){
    fin >> input;
}

int priority(char p_operator){
    switch(p_operator){
        case '(':
            return 0;
            break;

        case ')':
            return 0;
            break;

        case '+':
            return 1;
            break;

        case '-':
            return 1;
            break;

        case '*':
            return 2;
            break;

        case '/':
            return 2;
            break;
    }
    return 3;
}

//varianta cu stiva ca e mai usoara
//adaug un spatiu dupa fiecare numar in postfix
void convertInFix_PostFix(char Infix[],char Post_fix[])
{
    unsigned int index_In = 0,index_Post=0;
    stack <char> tool_stack;

    //traverse Infix string
    while(index_In < strlen(Infix)) {

        if (Infix[index_In] >= '0' && Infix[index_In] <= '9')
            Post_fix[index_Post++] = Infix[index_In++];

        if (Infix[index_In] == '(') {
            tool_stack.push('(');
            index_In++;
        }

        if (Infix[index_In] == ')') {
            while (tool_stack.top() != '(') {
                Post_fix[index_Post++] = tool_stack.top();
                tool_stack.pop();
            }
            index_In++;
        }

        if (Infix[index_In] == '+' || Infix[index_In] == '-' || Infix[index_In] == '/' || Infix[index_In] == '*') {
            output[index_Post++] = ' ';
            char operatorul = Infix[index_In];
            if (tool_stack.empty())
                tool_stack.push(operatorul);
            else {
                while (priority(operatorul) <= priority(tool_stack.top())) {
                    Post_fix[index_Post++] = tool_stack.top();
                    tool_stack.pop();
                    if(tool_stack.empty())  break;
                }
                tool_stack.push(operatorul);
            }
            index_In++;
        }

    }
    //poate se termina while-ul si noi mai avem operatori in stiva
    while(!tool_stack.empty()){
        if(tool_stack.top() != '(' && tool_stack.top() != ')')
            Post_fix[index_Post++] = tool_stack.top();
        tool_stack.pop();
    }
}

int calculate(char p_operator,int left,int right){
    switch(p_operator){
        case '+':
            return left+right;
            break;
        case '-':
            return left-right;
            break;
        case '*':
            return left*right;
            break;
        case '/':
            return left/right;
            break;
    }
    return 0;
}


int power(int a, int b)    //a is base, b is exponent
{
    if(b==0)
        return 1;
    if(b==1)
        return a;
    if(b%2 == 1)
        return (power(a,b-1)*a)%mod;
    int q = power(a,b/2);
    return (q*q)%mod;
}

int evaluate(char input[]){
    stack <int> tool_stack;
    ///luam fiecare element
    for(unsigned int index = 0; index < strlen(input); index++){
        if(input[index]=='+'||input[index]=='-'||input[index]=='*'||input[index]=='/') {///daca e operator
            char operatoR = input[index];//caracterul curent e operator
            int op1 = tool_stack.top(); tool_stack.pop();
            int op2 = tool_stack.top(); tool_stack.pop();
            //cout << op1 << operatoR << op2 << "push on stack (" << calculate(operatoR,op2,op1)<< ")\n";
            tool_stack.push(calculate(operatoR,op2,op1));
        }
        else {
            //daca e un numar, parcurg caracterele pana la ultima cifra si formez numarul si asa il pun pe stiva
            //ca altfel doar pun cifre pe stiva bagamias
            if(input[index] != ' '){
                unsigned int aux = index+1;
                unsigned int numar = (input[index]-'0'),step=1;
                if(aux < strlen(input)){
                    while(input[aux] >= '0' && input[aux] <= '9' && aux < strlen(input)){
                        numar = numar*power(10,step) + (input[aux]-'0');
                        aux++; step++;
                    }
                }
                index = aux-1;//trec mai departe in parcurgerea mare cu aux
                tool_stack.push(numar);
            }
        }
    }
    return tool_stack.top();///rezultatul e aici
}


int main(){
    Read();
    //cout << "input : " << input << "\n";
    convertInFix_PostFix(input,output);
    //cout << output << "\n";
    //cout << "output: " << output << "\n Rezultat : ";
    fout << evaluate(output);
    fin.close();
    fout.close();
    return 0;
}