Cod sursa(job #658818)

Utilizator blue_phoenixPosea Elena blue_phoenix Data 9 ianuarie 2012 17:16:35
Problema Evaluarea unei expresii Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.9 kb
#include <stdio.h>
#include <string.h>
#define maxn 100010

char buffer[maxn];
int numere[maxn],ind=-1;
char operatori[maxn];
int indop=-1;
//char precedenta[]="(-+*/)";//6 operatori

inline char precedenta(char c){
   switch(c){
     case '(':return 0;
     case '-':return 1;
     case '+':return 1;
     case '*':return 2;
     case '/':return 2;
     case ')':return 3;
   }
}

int main(){
   FILE *fin=fopen("evaluare.in","r");
   fscanf(fin,"%s",buffer);   
   int n=strlen(buffer);
   //printf("%s",buffer);
   int i=0;
   int nr;
   char aux;
   while(i<n){
      //printf("i=%d\n",i);
      //daca caracterul al i-lea e cifra=>parte dintr-un operand
     if(buffer[i]<='9' && buffer[i]>='0'){     //daca e numar, citesc tot numarul
        nr=0;
        while(buffer[i]<='9' && buffer[i]>='0' && i<n){
           nr*=10;
           nr+=buffer[i]-'0';
           i++;
        }
        numere[++ind]=nr;
        //printf("am citit un numar: %d\n",nr);
     }else{
      //daca e operator
          if(buffer[i]==')'){
              while(operatori[indop]!='('){
                 switch(operatori[indop]){
                    case '+':numere[ind-1]+=numere[ind];ind--;break;
                    case '-':numere[ind-1]-=numere[ind];ind--;break;
                    case '*':numere[ind-1]*=numere[ind];ind--;break;
                    case '/':numere[ind-1]/=numere[ind];ind--;break;
                 }
                indop--;
              }              
             //acum e '(', trebuie stearsa si ea
             indop--;
             //printf("am inchis o paranteza; sunt pe locul %d in stiva de operatori; ultimul nr din stiva de numere e %d\n",indop,numere[ind]);
          }else{
              aux=precedenta(buffer[i]);
              if(buffer[i]!='('){
                while(aux<=precedenta(operatori[indop]) && indop>=0){//cat timp ce adaug are precedenta mai mica ca ce e inainte
                   switch(operatori[indop]){
                      case '+':numere[ind-1]+=numere[ind];ind--;break;
                      case '-':numere[ind-1]-=numere[ind];ind--;break;
                      case '*':numere[ind-1]*=numere[ind];ind--;break;
                      case '/':/*printf("ind=%d\n",ind);*/numere[ind-1]/=numere[ind];ind--;break;
                   }
                  indop--;
                }    
              }          
              operatori[++indop]=buffer[i];
          }//else: caracterul curent e operator, dar nu e ')'
      i++;
    }//else e caracter, nu cifra
 }//while dupa buffer

 //acum calculez
    while(indop>=0){
         switch(operatori[indop]){
           case '+':numere[ind-1]+=numere[ind];ind--;break;
           case '-':numere[ind-1]-=numere[ind];ind--;break;
           case '*':numere[ind-1]*=numere[ind];ind--;break;
           case '/':numere[ind-1]/=numere[ind];ind--;break;
         }
         indop--;
  }            
  FILE *fout=fopen("evaluare.out","w");  
  fprintf(fout,"%d\n",numere[0]); 
return 0;
}