Sunteți pe pagina 1din 8

Evaluarea expresiilor aritmetice

De la simplu la compus
Evaluarea unor expresii aritmetice constituie un procedeu important att n
soft-ul financiar, educa ional, i nu n ultimul rnd n producerea compilatoarelor
pentru limbajele de programare. Anume din acest motiv a a tip de probleme se
ntlnesc des la olimpiezile colare de informatica.
Vom ncepe cu varianta cea mai simpl i pe parcurs vom analiza deosebirile la
nivel de programare odat ce complicm condi ia problemei.
. Expresia aritmetica ( doar !+" i !-" ) .
Enun :
#ndu-se o expresie aritmetic format doar din cifre $%..&' i operatorii
!( i !-" , s se calculeze valoarea expresiei.
Date de intrare:
)e prima linie a fi ierului expresie1.in se afl un ir de caractere format
din maxim %%%% de caractere reprezentnd expresia ce urmeaz s fie
evaluat.
Date de ie ire:
*n fi ierul expresie1.out se va afi a un singur numr reprezentnd
valoarea expresiei.
expresie1.in: expresie1.out:
+(,---.(&- %
Rezolvarea:
/ezolvarea este destul de vizibil , fiindc lucrm doar cu cifre , deci
unica ce avem de fcut este de a parcurge irul caracter cu caracter i de a
converta caracterul n cifr. 0onversia o facem utiliznd pozi ionarea
caracterelor ce reprezint cifre n tabelul A1022 i numerele lor de ordine3
Caracter: 4%4 , 44 , 4.4 , 4+4 , 5 464, 4&4
Numr de ordine ( ord(c) ): -6 , -& , ,% , , , 5 , ,7 , ,8
#e unde ob inem rela ia de conversie3 x = ord(ch) 4
9otodat, la fiecare pas avem grij de semn , care-l reprezentm n
variabila !semn" care are valoare cnd caracterul din fa a cifrei curente e
plus , i % cnd e minus.
)rogramul )ascal arat n felul urmtor3
)rogram expresie:
var s3ansistring:
i,suma,semn3longint:
begin
assign$input,;expresie.in;': reset$input':
readln$s':
i3<: semn3<: suma3<%:
=>ile i?<lengt>$s' do
begin
if semn< t>en suma3<suma(ord$s@iA'--6
else suma3<suma-ord$s@iA'(-6:
inc$i':
if i?<lengt>$s' t>en
if s@iA<;(; t>en semn3<
else semn3<%:
inc$i':
end:
assign$output,;expresie.out;': re=rite$output': =riteln$suma':
close$output':
end.


)entru cazul cnd lucrm cu numere, deja avem alt procedeu de convertire a irului
n numr3
x3<%:
=>ile $s@iAB<4%4' and $s@iA?<4&4' and $i?< lengt>$s'' do
begin
x3<$xC%'($ord$s@iA' D -6':
inc$i':
end:
*n continuare propunem problema anterioar , dar cu deosebirea c pe lng
operatorii !(" i !-" , mai apare operatorul !C" i !E" $div' .
Aceast problem poate fi rezolvat prin mai multe metode. Vom prezenta . din
ele3
)rima utilizeaz o stiv alocat static , defapt reprezint un vector doar c
lucrm cu ea dup principiul stivei $ F2FG , Fast 2n Fast Gut, adic H)rimul intrat e
i ultimul ie it" '.
A doua , la fel folose te stiv , doar c pe cea a calculatorului. #efapt metoda
const n recursivitate indirect , adic folosirea procedurile care se apeleaz una
pe alta , pentru a separa operatorii dup prioritate $ *nti se efectueaz opera iile div
i mod , apoi adunare i scdere'
#e i a doua metod este mult mai performant i compact n cod scris precum
i poate fi u or utilizat pentru cazurile cnd avem i alte opera ii specifice $ de
exemplu la nivel de bit3xor,and,or' sau paranteze ,totu i aceast metod necesit o
analiz atent .
Astfel )rezentm nti varianta programului cu stiva alocat static3
)rogram expresie.:
var s3ansistring:
i,vf,aux,semn,rasp3longint:
st3arraI @..%%%,A of longint:
function convert3longint:
var x3longint:
begin
x3<%:
=>ile $i?<lengt>$s''and$s@iAB<;%;'and$s@iA?<;&;' do
begin
x3<$xC%'($ord$s@iA' - -6':
inc$i':
end:
convert3<x:
end:
Jegin
assign$input,;expresie..in;': reset$input':
readln$s':
i3<: vf3<%: semn3<-:
=>ile i?<lengt>$s' do
begin
if semnB-+ t>en begin inc$vf': st@vfA3<semn: inc$vf': st@vfA3<convert: end
else
begin
aux3<convert:
if semn<-+ t>en aux3<st@vfA C aux
else aux3<st@vfA div aux:
st@vfA3<aux:
end:
if i?<lengt>$s' t>en
begin
if s@iA<;(; t>en semn3<-:
if s@iA<;-; t>en semn3<-.:
if s@iA<;C; t>en semn3<-+:
if s@iA<;E; t>en semn3<--:
inc$i':
end:
end:
i3<: rasp3<%:
=>ile i?<vf do begin
if st@iA<- t>en rasp3<rasp(st@i(A
else rasp3<rasp-st@i(A:
inc$i,.':
end:
assign$output,;expresie..out;': re=rite$output': =riteln$rasp':
close$output':
end.
Explica ie:
Kunc ia !convert" parcurge stringul i converteaz n numr pn cnd ajunge
la un semn sau la sfr itul stringului. *n programul principal parcurgem stringul i
dac semnul precedent este !(" sau !D" atunci punem n stiv semnul i numr
convertit. *n caz c semnul e !C" sau !E" atunci lum valoare din vrful stivei i
facem opera ia respectiv dintre vrful stivei i numrul convertit , dup care
rezultatul opera iei n punem n locul vrfului stivei. Fa sfr it parcurgem stiva i
efectum adunm sau scdem valoare din stiv la rezultatul final n dependen de
semnul !(" sau !D" din stiv , codificat cu valoarea - i -..
)entru varianta .-a vom aduga i condi ia ca s fie paranteze rotunde, defapt
aceast metod poate fi folosit pentru un numr mare de operatori , pentru
operatorii cu aceea i prioritate fcndu-se cte-o func ie aparte , fiecare apelndu-
se una pe alta pn la ultima cu prioritatea cea mai mare , care ncepe prima
procesarea convertnd irul de caractere n numr sau apelnd func ia ini ial
pentru a procesa o expresie parantezat. Fa sfr itul irul de caractere adugm un
oarecare simbol care nu figureaz n lista de operatori i cifre . Acest caracter face
mai u oar ie irea din recursie, neavnd nevoie s controlm de fiecare dat dac
i?<lengt>$s' ca nu cumva s apelm stringul n celulele inexistente .Astfel recursia
se va opri cnd va ajunge n acest caracter, deoarece el nu figureaz n nici un =>ile
din func iile recursive din program.
)rogramul )ascal arat n felul urmtor3
)rogram expresie+:
var s3ansistring:
i3longint:
Kunction factor3longint: for=ard:
Kunction factor.3longint: for=ard:
Kunction eval3longint:
var v3longint:
begin
v3<factor:
=>ile $s@iA<;(;' or $s@iA<;-;' do begin
if s@iA<;(; t>en begin inc$i': v3<v(factor: end
else begin inc$i': v3<v-factor: end:
end:
eval3<v:
end:
Kunction factor3longint:
var v3longint:
begin
v3<factor.:
=>ile $s@iA<;C;'or$s@iA<;E;' do begin
if s@iA<;C; t>en begin inc$i': v3<vCfactor. end
else begin inc$i': v3<v div factor.: end:
end:
factor3<v:
end:
function factor.3longint:
var v3longint:
begin
v3<%:
if s@iA<;$; t>en begin inc$i': v3<eval: inc$i': end
else
=>ile $s@iAB<;%;'and$s@iA?<;&;' do
begin
v3<$vC%'($ord$s@iA' - -6':
inc$i':
end:
factor.3<v:
end:
Jegin
assign$input,;expresie+.in;': reset$input':
assign$output,;expresie+.out;': re=rite$output':
readln$s': s3<s(;L;:
i3<:
=riteln$eval':
close$output':
end.
!ro"leme propuse:
Expresii #in$#ax
0onsiderati o expresie care contine numere naturale, paranteze, si operatorii binari m si M. m este
operatorul de minim si M este operatorul de maxim. Astfel, rezultatul operatiei A m B este
valoarea minima dintre A si B, iar rezultatul operatiei A M B este valoarea maxima dintre A si B.
#e exemplu, rezultatul 2m7 este 2, iar rezultatul 9M8 este 9. 0ei doi operatori au aceeasi
prioritate. Asta inseamna ca daca nu sunt paranteze, vor fi evaluati de la stanga la dreapta. #e
exemplu, rezultatul 1M22m13m789 este 13.
Cerinta
#andu-se o expresie care contine numere naturale, paranteze si acesti doi operatori, aflati
rezultatul obtinut.
Date de %ntrare
)rima linie a fisierului emm.in contine expresia data. Mu vor exista spatii, linia se termina cu
caracter de sfarsit de linie $care nu face parte din ea'.
Date de %esire
Afisati pe prima linie a fisierului emm.out rezultatul obtinut in urma evaluarii expresiei.
&estrictii si preci'ari
Fungimea unei expresii va fi mai mica sau egala cu 100.000
Mumerele care apar in expresie vor fi numere naturale cuprinse intre 0 si 1.000.000.000
9impul de execu ie pe test %.- sec
Exemple
emm.in emm.out
86 86
86m77m.+-N6&m,-N+N..m78 ,-
$$$86''' 86
$mmNNmNNmN%'mN
$.m.+N+m&.'N$&%m6&m66m68'm$$.&6N8'N.' 68
FinO-ul de pe infoarena3 >ttp3EEinfoarena.roEproblemaEemm
Alte probleme: >ttp3EEinfoarena.roEproblemaEbool

S-ar putea să vă placă și