Cod sursa(job #726021)

Utilizator alexa_mihaltanMihaltan Alexandra alexa_mihaltan Data 26 martie 2012 23:16:01
Problema Evaluarea unei expresii Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 4.92 kb
#include <iostream>
#include <fstream>
#include <iomanip>
using namespace std;
const int DIM_MAX_EXPRESIE = 100000;
// Tipurile de atomi acceptate de aplicatie enum TipAtom
{
 Termen,         // un numar
 DeschidereParanteza,  // )
 InchidereParanteza,   // (
 Plus,      // +
 Minus,      // -
 Inmultire,     // *
 Impartire     // /
};
// Informatiile referitoare la un atom
struct Atom
{
 TipAtom Tip;
int Prioritate;
long long Valoare;
// Constructorul pentru initializarea
// unui atom
 Atom(TipAtom tip = Termen,
    int prioritate = 0, long long valoare = 0)
 {
  Tip = tip;
  Prioritate = prioritate;
  Valoare = valoare;
 }
};
// Stivele si cozile folosite vor
// avea ca informatie utila atomi
typedef Atom TipStiva;
typedef Atom TipCoada;
#include "stiva.h"
#include "coada.h"
// Transforma expresia intr-o coada de atomi
Coada ParsareSir(char *expresie)
{
 Coada coada = CdCreare();
while (*expresie != '\0')
 {
    switch(*expresie)
    {
      case '+': CdAdauga(coada, Atom(Plus, 1)); break;
      case '-': CdAdauga(coada, Atom(Minus, 1)); break;
      case '*': CdAdauga(coada, Atom(Inmultire, 2)); break;
      case '/': CdAdauga(coada, Atom(Impartire, 2)); break;
      case '(': CdAdauga(coada, Atom(DeschidereParanteza, 0)); break;
      case ')': CdAdauga(coada, Atom(InchidereParanteza,  0)); break;
      default:
        // termen (numar intreg)
if (*expresie > '0' && *expresie <= '9')
        {
          // construim termenul
long long valoare = 0;
          while (*expresie >= '0' && *expresie <= '9')
          {
      valoare = valoare*10 + (*expresie - '0');
      expresie++;
          }
          // trebuie sa revenim la primul caracter
// de dupa numar
     expresie--;

// adaugam termenul in coada
     CdAdauga(coada, Atom(Termen,  0, valoare));
        }
    }
    // avansam la urmatorul caracter din expresie
  expresie++;
 } return coada;
}
// Transforma o expresie din forma normala
// infixata in forma poloneza postfixata
Coada FormaPoloneza(Coada& expresie)
{
// stiva folosita pentru stocarea temporara
 Stiva stiva = StCreare();
// coada pentru stocarea rezultatului (forma poloneza)
 Coada formaPoloneza = CdCreare();
 Atom atomStiva;
// parcurgem expresia initiala
while (!CdEGoala(expresie))
 {
  Atom atom = CdExtrage(expresie);
    switch (atom.Tip)
    {
    case Termen:
// se adauga direct in sirul rezultat
   CdAdauga(formaPoloneza, atom);
      break;

    case DeschidereParanteza:
// se adauga in stiva
   StAdauga(stiva, atom);
      break;
    case InchidereParanteza:
// se muta din stiva in rezultat toti operatorii
// pana la deschiderea parantezei
   atomStiva = StExtrage(stiva);
      while (atomStiva.Tip != DeschidereParanteza)
      {
    CdAdauga(formaPoloneza, atomStiva);
    atomStiva = StExtrage(stiva);
      }
      break;
    default: // operator
      while (!StEGoala(stiva) && StVarf(stiva).Prioritate >
atom.Prioritate)
    CdAdauga(formaPoloneza, StExtrage(stiva));
   StAdauga(stiva, atom);
    }
 }
// mutam toate elementele ramase in rezultat
while (!StEGoala(stiva))
  CdAdauga(formaPoloneza, StExtrage(stiva));
return formaPoloneza;
}
// Evaluaeaza o expresie aflata in
// forma poloneza postfixata
long long Evaluare(Coada& formaPoloneza)
{
// stiva de termeni folosita pentru evaluare
 Stiva stiva = StCreare();

// parcurgem expresia in forma poloneza
while (!CdEGoala(formaPoloneza))
 {
  Atom atom = CdExtrage(formaPoloneza);
    if (atom.Tip == Termen)
      // daca avem un termen atunci il adaugam in stiva
   StAdauga(stiva, atom);
    else
    {
      // daca avem un operator atunci scoatem
// ultimii doi termeni din stiva,  efectuam operatia       // si punem rezultatul pe stiva
   Atom termen1 = StExtrage(stiva);
   Atom termen2 = StExtrage(stiva);
      switch (atom.Tip)
      {
      case Plus:
    StAdauga(stiva, Atom(Termen, 0, termen1.Valoare +
termen2.Valoare));
        break;
      case Minus:
    StAdauga(stiva, Atom(Termen, 0, termen2.Valoare -
termen1.Valoare));
        break;
      case Inmultire:
    StAdauga(stiva, Atom(Termen, 0, termen1.Valoare *
termen2.Valoare));
        break;
      case Impartire:
    StAdauga(stiva, Atom(Termen, 0, termen2.Valoare /
termen1.Valoare));
        break;
      }
    }
 }
// rezultatul expresiei este valoarea
// ultimului termen ramas in stiva
return StExtrage(stiva).Valoare;
}
void main()
{
// alocare spatiu pentru expresia citita
char *sir = new char[DIM_MAX_EXPRESIE];
ifstream fin("evaluare.in");
fin.getline(sir, 100000);

// Faza 1: Construirea cozii de atomi
 Coada expresie = ParsareSir(sir);
// Faza 2: Transformarea in forma poloneza
 Coada formaPoloneza = FormaPoloneza(expresie);
// Faza 3: Evaluarea expresiei
long long rezultat = Evaluare(formaPoloneza);
fin.close();
ofsteram fout("evaluare.out");
// afisarea retzultatului
 fout << rezultat << endl;
 fout.close();
}