Pagini recente » Cod sursa (job #1749667) | Cod sursa (job #102382) | Cod sursa (job #1623285) | Cod sursa (job #2090930) | Cod sursa (job #726021)
Cod sursa(job #726021)
#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();
}