Pagini recente » Cod sursa (job #694538) | Cod sursa (job #1878576) | Cod sursa (job #1639771) | Cod sursa (job #2840950) | Cod sursa (job #2314548)
/*problema evaluare de pe infoarena, evaluarea unei expresii aritmetice
reprezentam expresia cu un arbore binar folosit ptr forma poloneza,
unde operatorii sunt pe noduri interioare, iar operanzii pe frunze
evit recursivitatea indirecta si folosesc metoda cu prioritati ale operatorilor
operatorii - si + au, initial, prioritatea 1, iar * si / 10.
Aparitia unei paranteze rotunde, creste prioritatea operatorilor ce urmeaza cu 10, iar una inchisa, scade cu 10
Prioritatea unui operand este 100005
Parantezele nu au pondere si sunt excluse in vectorul pond
Retin prioritatile in vectorul pond
Arborele va fi retinut dinamic, fiecare nod avand informatia (operand sau operator) si doua campuri de adresa,
ptr fiul stang si ptr cel drept.
Limita de valori ptr operanzi este 1 000 000 000
vom lua 1 000 000 001 ca fiind +, 1 000 000 002, drept -, 1 000 000 003 *, 1 000 000 004 /
Sirul initial se va prelucra intr-un vector nou, numit nou, ce va retine operatorii ca si intregii de mai sus si operanzii
In acelasi timp cu constructia vectorului de mai sus, se va construi si vectorul de prioritati
Alegerea nodului curent din arbore se face astfel:
Se foloseste divide et impera
Cautarea incepe cu limitele 0 si ultima componenta a vectorului de ponderi
Se cauta cea mai mica pondere intre aceste limite(pozitia poz) si se completeaza informatia cu acel caracter
Daca limita inferioara coincide cu cea superioara am dat de o frunza si se completeaza cu null campurile de adresa
Altfel, fiul stang va fi nodul rezultat in urma apelului cu 1, poz-1, iar fiul drept ce rezulta in urma apelului (poz+1, ls)
Functia va intoarce nodul astfel construit, prn urmare, in final, va returna adresa radacinii arborelui
Daca vrem forma poloneza prefixata a expresiei, vom folosi o parcurgere radacina stanga dreapta, iar daca vrem cea postfixata,
stanga dreapta radacina
Evaluarea expresiei se va face tot dupa tehnica Divide et Impera
Daca nodul nu este terminal se retine valoarea returnata de apelul cu fiul stang si cea rezultata de la fiul drept
si apoi se aplica operatorul continut de csmpul informatie
contrar, se intoarce operandul
*/
#include <fstream>
#define dim 100005
#define plus 1000000001
#define minus 1000000002
#define ori 1000000003
#define div 1000000004
using namespace std;
char sir[dim];
int pond[dim];
int nou[dim];
struct nod
{
int info;
nod* stg;
nod *drp;
};
nod * generare(int li, int ls)
{
nod* rez;
int minim,poz,i;
//parcurgem vectorul de ponderi de la dreapta la stanga si retinem in poz, pozitia ponderii celei mai mici
minim=pond[ls];
poz=ls;
for(i=ls-1;i>=li;i--)
if(pond[i]<minim)
{
minim=pond[i];
poz=i;
}
//aloc dinamic nodul pe care il voi adauga in arbore si completez campurile
rez=new nod;
rez->info=nou[poz];
if(li==ls)
{
rez->stg=NULL;
rez->drp=NULL;
}
else
{
rez->stg=generare(li,poz-1);
rez->drp=generare(poz+1,ls);
}
return rez;
}
int evaluare(nod*rad)
{
switch(rad->info)
{
case plus: return evaluare(rad->stg)+evaluare(rad->drp);break;
case minus: return evaluare(rad->stg)-evaluare(rad->drp);break;
case ori: return evaluare(rad->stg)*evaluare(rad->drp);break;
case div: return evaluare(rad->stg)/evaluare(rad->drp);break;
default: return rad->info;
}
}
int main()
{
ifstream fin("evaluare.in");
ofstream fout("evaluare.out");
fin.get(sir, dim);
int pondere=0,val;
//construiesc vectorul de intregi si vectorul corespunzator de ponderi
unsigned int i;
int j=-1;
for(i=0;sir[i]!=0;i++)
{
switch(sir[i])
{
case '(': pondere+=10;break;
case ')': pondere-=10;break;
case '+': nou[++j]=plus;pond[j]=pondere+1;break;
case '-': nou[++j]=minus;pond[j]=pondere+1;break;
case '*': nou[++j]=ori;pond[j]=pondere+10;break;
case '/': nou[++j]=div;pond[j]=pondere+10;break;
default:
for(val=0;sir[i]>='0' && sir[i]<='9';i++)
val=val*10+(sir[i]-'0');
i--;//i va pointa catre primul caracter non cifra si apoi cu i++ din for il va sari, decrementam
nou[++j]=val;pond[j]=dim;
}
}
nod*rad=generare(0,j);
fout<<evaluare(rad);
return 0;
}