You are on page 1of 23

Arithmetic Expression Evaluation

The stack organization is very effective in evaluating arithmetic expressions. Expressions are
usually represented in what is known as Infix notation, in which each operator is written between two
operands (i.e., A + B). With this notation, we must distinguish between ( A + B )*C and A + ( B * C ) by
using either parentheses or some operator-precedence convention. Thus, the order of operators and
operands in an arithmetic expression does not uniquely determine the order in which the operations are to
be performed.

Polish notation (prefix notation)


It refers to the notation in which the operator is placed before its two operands. Here no
parentheses are required, i.e., +AB
Reverse Polish notation(postfix notation)
It refers to the analogous notation in which the operator is placed after its two operands. Again, no
parentheses is required in Reverse Polish notation, i.e., AB+

Stack organized computers are better suited for post-fix notation then the traditional infix notation.
Thus the infix notation must be converted to the post-fix notation. The conversion from infix notation to
post-fix notation must take into consideration the operational hierarchy.
There are 3 levels of precedence for 5 binary operators as given below:
Highest: Exponentiation (^)
Next highest: Multiplication (*) and division (/)
Lowest: Addition (+) and Subtraction (-)
For example:
• Infix notation: (A-B)*[C/(D+E)+F]
• Post-fix notation: AB- CDE +/F +*
Here, we first perform the arithmetic inside the parentheses (A-B) and (D+E). The division of
C/(D+E) must done prior to the addition with F. After that multiply the two terms inside the parentheses
and bracket. Now we need to calculate the value of these arithmetic operations by using stack.
The procedure for getting the result is:
• Convert the expression in Reverse Polish notation( post-fix notation).
• Push the operands into the stack in the order they are appear.
• When any operator encounter then pop two topmost operands for executing the operation.
• After execution push the result obtained into the stack.
• After the complete execution of expression the final result remains on the top of the stack.
For example:
• Infix notation: (2+4) * (4+6)
• Post-fix notation: 2 4 + 4 6 + *
Result: 60
The stack operations for this expression evaluation is shown below:

pag. 1
Expression Evaluation
Evaluate an expression represented by a String. Expression can contain parentheses, you can
assume parentheses are well-matched. For simplicity, you can assume only binary operations allowed are
+, -, *, and /.
Arithmetic Expressions can be written in one of three forms:
• Infix Notation: Operators are written between the operands they operate on, e.g. 3 + 4 .
• Prefix Notation: Operators are written before the operands, e.g + 3 4
• Postfix Notation: Operators are written after operands.
Infix Expressions are harder for Computers to evaluate because of the additional work needed to
decide precedence. Infix notation is how expressions are written and recognized by humans and,
generally, input to programs. Given that they are harder to evaluate, they are generally converted to one
of the two remaining forms.
A very well known algorithm for converting an infix notation to a postfix notation is Shunting Yard
Algorithm by Edgar Dijkstra. This algorithm takes as input an Infix Expression and produces a queue that
has this expression converted to a postfix notation. Same algorithm can be modified so that it outputs
result of evaluation of expression instead of a queue. Trick is using two stacks instead of one, one for
operands and one for operators.
1. While there are still tokens to be read in,
1.1 Get the next token.
1.2 If the token is:
1.2.1 A number: push it onto the value stack.
1.2.2 A variable: get its value, and push onto the value stack.
1.2.3 A left parenthesis: push it onto the operator stack.
1.2.4 A right parenthesis:
1 While the thing on top of the operator stack is not a
left parenthesis,
1 Pop the operator from the operator stack.
2 Pop the value stack twice, getting two operands.
3 Apply the operator to the operands, in the correct order.
4 Push the result onto the value stack.
2 Pop the left parenthesis from the operator stack, and discard it.
1.2.5 An operator (call it thisOp):
1 While the operator stack is not empty, and the top thing on the
operator stack has the same or greater precedence as thisOp,
1 Pop the operator from the operator stack.
2 Pop the value stack twice, getting two operands.
3 Apply the operator to the operands, in the correct order.
4 Push the result onto the value stack.
2 Push thisOp onto the operator stack.
2. While the operator stack is not empty,
1 Pop the operator from the operator stack.
2 Pop the value stack twice, getting two operands.
3 Apply the operator to the operands, in the correct order.
4 Push the result onto the value stack.
3. At this point the operator stack should be empty, and the value
stack should have only one value in it, which is the final result.

Implementation
// CPP program to evaluate a given expression where tokens are separated by space.
#include <bits/stdc++.h>
using namespace std;
// Function to find precedence of operators.
int precedence(char op){
if(op == '+'||op == '-')
pag. 2
return 1;
if(op == '*'||op == '/')
return 2;
return 0;
}
// Function to perform arithmetic operations.
int applyOp(int a, int b, char op){
switch(op){
case '+': return a + b;
case '-': return a - b;
case '*': return a * b;
case '/': return a / b;
}
}
// Function that returns value of expression after evaluation.
int evaluate(string tokens){
int i;
// stack to store integer values.
stack <int> values;
// stack to store operators.
stack <char> ops;
for(i = 0; i < tokens.length(); i++){
// Current token is a whitespace, skip it.
if(tokens[i] == ' ')
continue;
// Current token is an opening brace, push it to 'ops'
else if(tokens[i] == '('){
ops.push(tokens[i]);
}

// Current token is a number, push it to stack for numbers.


else if(isdigit(tokens[i])){
int val = 0;
// There may be more than one digits in number.
while(i < tokens.length() &&
isdigit(tokens[i])) {
val = (val*10) + (tokens[i]-'0');
i++;
}
i--;
values.push(val);
}
// Closing brace encountered, solve entire brace.
else if(tokens[i] == ')') {
while(!ops.empty() && ops.top() != '(') {
int val2 = values.top();
values.pop();

int val1 = values.top();


values.pop();

char op = ops.top();
ops.pop();
values.push(applyOp(val1, val2, op));
}
// pop opening brace.

pag. 3
ops.pop();
}
// Current token is an operator.
else{
// While top of 'ops' has same or greater precedence to current token, which
// is an operator. Apply operator on top of 'ops' to top two elements in values stack.
while(!ops.empty() && precedence(ops.top())
>= precedence(tokens[i])){
int val2 = values.top();
values.pop();

int val1 = values.top();


values.pop();

char op = ops.top();
ops.pop();
values.push(applyOp(val1, val2, op));
}
// Push current token to 'ops'.
ops.push(tokens[i]);
}
}
// Entire expression has been parsed at this point, apply remaining ops to remaining values.
while(!ops.empty()){
int val2 = values.top();
values.pop();

int val1 = values.top();


values.pop();

char op = ops.top();
ops.pop();
values.push(applyOp(val1, val2, op));
}
// Top of 'values' contains result, return it.
return values.top();
}
int main() {
cout << evaluate("10 + 2 * 6") << "\n";
cout << evaluate("100 * 2 + 12") << "\n";
cout << evaluate("100 * ( 2 + 12 )") << "\n";
cout << evaluate("100 * ( 2 + 12 ) / 14");
return 0;
}

Output:
22
212
1400
100

Time Complexity: O(n)


Space Complexity: O(n)

pag. 4
Verificare:
#include <bits/stdc++.h>

using namespace std;


char expr[256];//expresia
int precedenta(char op){
if(op=='+' || op=='-') return 1;
if(op=='*' || op=='/') return 2;
return 0;//paranteze
}
int aplicaOP(int x, int y, char op){
switch(op){
case '+': return x+y;
case '-': return x-y;
case '*': return x*y;
case '/': return x/y;
}
}
int evaluare(char expr[]){
//stiva pentru valorile intregi
stack <int> oz;//operanZi
//stiva pentru operatori
stack <char> ot;//operaTori
//traversam expresia si formam cele 2 stive
for(int i=0;i<strlen(expr);i++){
//peste spatii vom sari
if(expr[i]==' ') continue;
//paranteza deschisa
if(expr[i]=='('){
ot.push(expr[i]);//adauga in stiva operatorilor
}else
//operand (constanta sau variabila)
if(isdigit(expr[i])){//il adaug in stiva operanzi
int val=0;//se evalueaza constanta
//operandul poate avea mai mult de 1 cifra
while(isdigit(expr[i]) && i<strlen(expr)){
val=val*10 + expr[i]-'0';
i++;
}
i--;//revine la caracterul curent
oz.push(val);
//cout<<"\noz="<<oz.top()<<"\n";
}//operandul

else if(expr[i]==')'){//paranteza inchisa


//se evaluyeaza expresia dintre paranteze
while(!ot.empty() && ot.top()!='('){
int val2=oz.top();oz.pop();
int val1=oz.top();oz.pop();
char op=ot.top();ot.pop();
//rezultatul in stiva oz
oz.push(aplicaOP(val1,val2,op));/
}
ot.pop();//se scoate paranteza deschisa
}
else//am un operator

pag. 5
{
//cout<<"Un operator";
//cat timp operatorul din varf are precedenta mai mare sau egala decat cel curent gasit
//se aplica operatorul din varf pe cei 2 operanzi din varful stivei oz
//iar rezultatul se pune in varf
while(!ot.empty() && precedenta(ot.top())>=precedenta(expr[i])){
int val2=oz.top();oz.pop();
int val1=oz.top();oz.pop();
char op=ot.top();ot.pop();
//rezultatul in stiva oz
oz.push(aplicaOP(val1,val2,op));
}
ot.push(expr[i]);
//cout<<"\not="<<ot.top()<<"\n";
}//operator

}//sfarsit traversare
//stivele sunt formate, se evalueaza si se golesc pe rand
while(!ot.empty()){
int val2=oz.top();oz.pop();
int val1=oz.top();oz.pop();
char op=ot.top();ot.pop();

oz.push(aplicaOP(val1,val2,op));
}
return oz.top();//rezultatul final al expresiei
}
int main(){
cin.get(expr,255);
cout<<"Vom evalua expresia: "<<expr;
cout<<"\nRezultatul obtinut: "<<evaluare(expr);
return 0;
}

pag. 6
Evaluation of Prefix Expressions
Prefix and Postfix expressions can be evaluated faster than an infix expression. This is because we
don’t need to process any brackets or follow operator precedence rule. In postfix and prefix expressions
which ever operator comes before will be evaluated first, irrespective of its priority. Also, there are no
brackets in these expressions. As long as we can guarantee that a valid prefix or postfix expression is
used, it can be evaluated with correctness.
We can convert infix to postfix and can covert infix to prefix.
The method is similar to evaluating a postfix expression. Please read Evaluation of Postfix Expression
to know how to evaluate postfix expressions.

Algorithm

EVALUATE_POSTFIX(STRING)
Step 1: Put a pointer P at the end of the end
Step 2: If character at P is an operand push it to Stack
Step 3: If the character at P is an operator pop two
elements from the Stack. Operate on these elements
according to the operator, and push the result
back to the Stack
Step 4: Decrement P by 1 and go to Step 2 as long as there
are characters left to be scanned in the expression.
Step 5: The Result is stored at the top of the Stack,
return it
Step 6: End

Expression: +9*26

Character | Stack | Explanation


Scanned | (Front to |
| Back) |
-------------------------------------------
6 6 6 is an operand,
push to Stack
2 62 2 is an operand,
push to Stack
* 12 (6*2) * is an operator,
pop 6 and 2, multiply
them and push result
to Stack
9 12 9 9 is an operand, push
to Stack
+ 21 (12+9) + is an operator, pop
12 and 9 add them and
push result to Stack
Result: 21
Examples: Input : -+8/632
Output : 8
Input : -+7*45+20
Output : 25

Complexity The algorithm has linear complexity since we scan the expression once and perform at most
O(N) push and pop operations which take constant time.

pag. 7
Implementation
// CPP program to evaluate a prefix expression.
#include <bits/stdc++.h>
using namespace std;
bool isOperand(char c) {
// If the character is a digit then it must
// be an operand
return isdigit(c);
}
double evaluatePrefix(string exprsn) {
stack<double> Stack;
for (int j = exprsn.size() - 1; j >= 0; j--) {
// Push operand to Stack to convert exprsn[j] to digit subtract '0' from exprsn[j].
if (isOperand(exprsn[j]))
Stack.push(exprsn[j] - '0');
else {
// Operator encountered Pop two elements from Stack
double o1 = Stack.top();
Stack.pop();
double o2 = Stack.top();
Stack.pop();
// Use switch case to operate on o1 and o2 and perform o1 O o2.
switch (exprsn[j]) {
case '+':
Stack.push(o1 + o2);
break;
case '-':
Stack.push(o1 - o2);
break;
case '*':
Stack.push(o1 * o2);
break;
case '/':
Stack.push(o1 / o2);
break;
}
}
}
return Stack.top();
}
int main() {
string exprsn = "+9*26";
cout << evaluatePrefix(exprsn) << endl;
return 0;
}

Output:
21
Note:
To perform more types of operations only the switch case table needs to be modified. This
implementation works only for single digit operands. Multi-digit operands can be implemented if some
character like space is used to separate the operands and operators.

pag. 8
Verificare
#include <bits/stdc++.h>

using namespace std;


char expr[256];//expresia

int aplicaOP(int x, int y, char op){


switch(op){
case '+': return x+y;
case '-': return x-y;
case '*': return x*y;
case '/': return x/y;
}
}
int evaluare(char expr[]){
//stiva pentru valorile intregi
stack <int> oz;//operanZi
int i;
//traversam expresia si formam stiva
for(i=strlen(expr)-1;i>=0;i--){
//peste spatii vom sari
if(expr[i]==' ') continue;
//operand (constanta sau variabila)
if(isdigit(expr[i])){//il adaug in stiva
int val=0;//se evalueaza constanta
int p=1;
//operandul poate avea mai mult de 1 cifra
while(isdigit(expr[i]) && i<strlen(expr)){
val=val + p * (expr[i]-'0');
p*=10;
i--;
}
//i++;//revine la caracterul curent
oz.push(val);
//cout<<"\noz="<<oz.top()<<"\n";
}//operandul
else//am un operator
{
//cout<<"Un operator";
//se aplica operatorul din varf pe cei 2 operanzi din varful stivei
//iar rezultatul se pune in varf
int val1=oz.top();oz.pop();
int val2=oz.top();oz.pop();
//rezultatul in stiva oz
oz.push(aplicaOP(val1,val2,expr[i]));
//cout<<"\noz="<<oz.top()<<"\n";
}//operator
}//sfarsit traversare
return oz.top();//rezultatul final al expresiei
}
int main(){
cin.get(expr,255);//separare prin spatii
cout<<"Vom evalua expresia: "<<expr;
cout<<"\nRezultatul obtinut: "<<evaluare(expr);
return 0;
}

pag. 9
Aplicatie: ACSL – Contest#4 – Intermediate Division
#include <bits/stdc++.h>
//exemplu1 //exemplu3
//Input * + 4 5 - 3 1 //Input + > 8 * 2 7 9 6
//Output 18 //Output 20

//exemplu2 //exemplu4
//Input @ - 8 9 7 6 //Input - @ - 3 5 7 * 2 4 > * 4 6 * 3 7 * 9 3
//Output 6 //Output -19

//exemplu5
//Input * 7 - + 4 6 > 0 - 2 3 1
//Output 63
using namespace std;
char expr[256];//expresia
//opreranzi formati dintr-o singura cifra
//operatori binari +, -, *
//operatori ternari : >cea mai mare valoare dintre a,b,c si @ b daca a pozitiv, c in caz contrar
//separare cel putin un spatiu
int aplicaOP_bin(int a, int b, char op){
switch(op){
case '+': return a+b;
case '-': return a-b;
case '*': return a*b;
}
}
int aplicaOP_ter(int a, int b, int c,char op){
switch(op){
case '@': if(a>0) return b;
else return c;
case '>': { if(a>b && a>c) return a;
if(b>a && b>c) return b;
if(c>a && c>b) return c;
}
}
}
int evaluare(char expr[]){
//stiva pentru valorile intregi
stack <int> oz;//operanZi
int i;
//traversam expresia si formam stiva
for(i=strlen(expr)-1;i>=0;i--){
while(expr[i]==' ') i--; //peste spatii vom sari
//operand (constanta sau variabila)
if(isdigit(expr[i])){//il adaug in stiva
int val=0;//se evalueaza constanta
int p=1;
//in cazul in care operandul ar avea mai mult de 1 cifra
while(isdigit(expr[i]) && i<strlen(expr)){
val=val + p * (expr[i]-'0');
p*=10;
i--;
}
oz.push(val);
}//operandul

pag. 10
else//am un operator
{
while(expr[i]==' ') i--;//daca sunt mai multe spatii le sar
//operator binar
if(expr[i]=='+' || expr[i]=='-' || expr[i]=='*') {
int val1=oz.top();oz.pop();
int val2=oz.top();oz.pop();
oz.push(aplicaOP_bin(val1,val2,expr[i]));//adaug rezultatul in stiva
}
//operator ternar
if(expr[i]=='>' || expr[i]=='@') {
int val1=oz.top();oz.pop();
int val2=oz.top();oz.pop();
int val3=oz.top();oz.pop();
oz.push(aplicaOP_ter(val1,val2,val3,expr[i]));//adaug rezultatul in stiva
}
}//operator
}//sfarsit traversare
return oz.top();//rezultatul final al expresiei
}
int main(){
cin.get(expr,255);//separare prin spatii
cout<<"Vom evalua expresia: "<<expr;
cout<<"\nRezultatul obtinut: "<<evaluare(expr);
return 0;
}

pag. 11
Infix to Postfix
The postfix expressions can be evaluated easily using a stack.
Infix: a+(b*c)+d
Postfix: abc*+d+

Algorithm
1. Scan the infix expression from left to right.
2. If the scanned character is an operand, output it.
3. Else,
3.1. If the precedence of the scanned operator is greater than the precedence of the operator
in the stack(or the stack is empty or the stack contains a ‘(‘, ‘)’, push it.
3.2. Else, Pop all the operators from the stack which are greater than or equal to in
precedence than that of the scanned operator. After doing that Push the scanned operator to
the stack. (If you encounter parenthesis while popping then stop there and push the
scanned operator in the stack.)
4. If the scanned character is an ‘(‘, push it to the stack.
5. If the scanned character is an ‘)’, pop the stack and output it until a ‘(‘ is encountered, and
discard both the parenthesis.
6. Repeat steps 2-6 until infix expression is scanned.
7. Print the output
8. Pop and output from the stack until it is not empty.

Implementation
#include<bits/stdc++.h>
using namespace std;
char expr[256];//forma infix
char new_s[256];//noul string care va retine forma postfixata
//Precedenta operatorilor
int prec(char c){
if(c == '^') return 3;
else if(c == '*' || c == '/') return 2;
else if(c == '+' || c == '-') return 1;
else return 0;
}
void infixToPostfix(char s[]){
stack<char> st;//stiva
int j=0;
for(int i = 0; i < strlen(s); i++){
// Operandul il adaug in noul string
if((s[i] >= 'a' && s[i] <= 'z')||(s[i] >= 'A' && s[i] <= 'Z')) new_s[j]=s[i],j++;
else if(s[i] == '(') st.push('('); // Daca avem ‘(‘ o punem in stiva
// Daca avem ‘)’, pop si adaug in noul string din stiva pana cand intalnesc ‘(‘
else if(s[i] == ')'){
while(!st.empty() && st.top() != '('){
new_s[j] = st.top(), j++;
st.pop();
}
if(st.top() == '(') st.pop();
}

pag. 12
else{//Daca avem un operator
//ii scot din stiva pe cei cu precedenta mai mare sau egala cu el si ii pun in noul string
while(!st.empty() && prec(s[i]) <= prec(st.top())){
new_s[j] = st.top(), j++;
st.pop();
}
st.push(s[i]);//il adaug in stiva
}
}
//Scot toate elemetele care au mai ramas in stiva
while(!st.empty()){
new_s[j] = st.top(), j++;
st.pop();
}
cout << new_s << endl;
}
int main(){
cin.get(expr,255);
cout<<"Se transforma expresia: "<<expr<<"\nIn forma PostFixata: ";
infixToPostfix(expr);
return 0;
}

Input a+b*(c^d-e)^(f+g*h)-i
Output abcd^e-fgh*+^*+i-

Input a+b*(c^d-e)
Output abcd^e-*+

Input a+b*(c-d)
Output abcd-*+

pag. 13
Postfix to Infix
Postfix notation, also known as reverse Polish notation, is a syntax for mathematical expressions
in which the mathematical operator is always placed after the operands.
Complex expressions using standard parenthesized infix notation are often more readable than the
corresponding postfix expressions. Consequently, we would sometimes like to allow end users to work
with infix notation and then convert it to postfix notation for computer processing. Sometimes, moreover,
expressions are stored or generated in postfix, and we would like to convert them to infix for the purpose
of reading and editing.
Examples:
Postfix: abc++ Postfix: ab*c+
Infix: (a + (b + c)) Infix: ((a*b)+c)
Algorithm
1.While there are input symbol left
1.1. Read the next symbol from the input.
2. If the symbol is an operand
2.1. Push it onto the stack.
3. Otherwise,
3.1. the symbol is an operator.
3.2. Pop the top 2 values from the stack.
3.3. Put the operator, with the values as arguments and form a string.
3.4. Push the resulted string back to stack.
4. If there is only one value in the stack
4.1. That value in the stack is the desired infix string.
Implementation
#include <bits/stdc++.h>
using namespace std;
string expr;//forma postfix
bool isOperand(char x){
return (x >= 'a' && x <= 'z') || (x >= 'A' && x <= 'Z');
}
string getInfix(string s){
stack <string> st;
for (int i=0; i<s.size(); i++){
if (isOperand(s[i])){ // Push operanzi
string op(1,s[i]);
st.push(op);
}
else{//operator
string op1 = st.top();
st.pop();//scot 2 operanzi
string op2 = st.top();
st.pop();
st.push("(" + op2 + s[i] + op1 + ")");//aplic operatorul
}
}
return st.top();//Singurul element ramas in stiva va fi expresia ceruta
}
int main() {
cin>>expr;
cout<<"Se transforma expresia: "<<expr<<"\nIn forma InFix: "<<getInfix(expr);
return 0;
}

pag. 14
Postfix to Prefix
Conversion of Postfix expression directly to Prefix without going through the process of
converting them first to Infix and then to Prefix is much better in terms of computation and better
understanding the expression.
Examples:
Postfix: AB+CD-* Postfix: ABC/-AK/L-*
Prefix : *+AB-CD Prefix: *-A/BC-/AKL
Explanation: Explanation:
Postfix to Infix: (A+B) * (C-D) Postfix to Infix: ((A-(B/C))*((A/K)-L))
Infix to Prefix: *+AB-CD Infix to Prefix: *-A/BC-/AKL

Algorithm
1. Read the Postfix expression from left to right
2. If the symbol is an operand, then push it onto the Stack
3. If the symbol is an operator, then pop two operands from the Stack
3.1. Create a string by concatenating the two operands and the operator before them.
string = operator + operand2 + operand1
3.2. And push the resultant string back to Stack
4. Repeat the above steps until end of Prefix expression.

Implementation
#include <iostream> #include <stack>
using namespace std;
string expr;//forma postfix
bool isOperator(char x){
switch (x) {
case '+':
case '-':
case '/':
case '*':
return true;}
return false;
}
string postToPre(string post_s){
stack<string> st;
// length of expression
int length = post_s.size();

// reading from right to left


for (int i = 0; i < post_s.size(); i++) {
if (isOperator(post_s[i])){//verific daca avem operator
string op1 = st.top();st.pop();
string op2 = st.top();st.pop();
string temp = post_s[i] + op2 + op1; // concatenez operanzii cu operatorul
st.push(temp); // Push string-ul in stiva
}else//daca este operand
{ st.push(string(1, post_s[i])); // push operand in stiva
}
}
return st.top();// varful stivei contine expresia in forma PreFix
}
int main(){
cin>>expr;
cout<<"Se transforma expresia PostFix: "<<expr<<"\nIn forma PreFix: "<< postToPre(expr);
return 0;
}
pag. 15
Infix to Prefix
Given an Infix expression, convert it into a Prefix expression using two stacks, one stack for
storing operators and other to store operands.
Examples:
InFix: A * B + C / D InFix: (A - B/C) * (A/K-L)
PreFix: + * A B/ C D PreFix: *-A/BC-/AKL

Algorithm
1. Traverse the infix expression and check if given character is an operator or an operand.
2. If it is an operand, then push it into operand stack.
3. If it is an operator, then check if priority of current operator is greater than or less than or equal to the
operator at top of the stack.
3.1. If priority is greater, then push operator into operator stack.
3.2. Otherwise pop two operands from operand stack, pop operator from operator stack and push
string operator + operand1 + operand 2 into operand stack. Keep popping from both stacks and
pushing result into operand stack until priority of current operator is less than or equal to operator
at top of the operator stack.
3.3. If current character is ‘(‘, then push it into operator stack.
3.4. If current character is ‘)’, then check if top of operator stack is opening bracket or not. If not
pop two operands from operand stack, pop operator from operator stack and push string operator +
operand1 + operand 2 into operand stack. Keep popping from both stacks and pushing result into operand
stack until top of operator stack is an opening bracket.
4. The final prefix expression is present at top of operand stack.

Time Complexity: O(n)


Auxiliary Space: O(n)

Implementation
#include <bits/stdc++.h>
using namespace std;
string expr;//forma infix
bool isOperator(char c){
return (!isalpha(c) && !isdigit(c));
}
int getPriority(char C){
if (C == '-' || C == '+')return 1;
if (C == '*' || C == '/') return 2;
if (C == '^') return 3;
return 0;
}
string infixToPrefix(string infix_s){
stack<char> ops;//stiva operatori
stack<string> oz;//stiva operanzi
for (int i = 0; i < infix_s.length(); i++){
// If current character is an opening bracket, then push into the operators stack.
if (infix_s[i] == '(') ops.push(infix_s[i]);
// If current character is a closing bracket, then pop from
// both stacks and push result in operands stack until
// matching opening bracket is not found.
else if (infix_s[i] == ')'){
while (!ops.empty() && ops.top() != '(') {
string op1 = oz.top();oz.pop();// operand 1
pag. 16
string op2 = oz.top();oz.pop();// operand 2
char op = ops.top();ops.pop();// operator
// Add operands and operator in form operator + operand1 + operand2.
string tmp = op + op2 + op1;
oz.push(tmp);
}
ops.pop();// Pop opening bracket from stack.
}
// If current character is an operand then push it into operands stack.
else if (!isOperator(infix_s[i])) {
oz.push(string(1, infix_s[i]));
}
// If current character is an operator, then push it into
// operators stack after popping high priority operators from
// operators stack and pushingresult in operands stack.
else {
while (!ops.empty() && getPriority(infix_s[i]) <= getPriority(ops.top())) {
string op1 = oz.top(); oz.pop();
string op2 = oz.top(); oz.pop();
char op = ops.top(); ops.pop();
string tmp = op + op2 + op1;
oz.push(tmp);
}
ops.push(infix_s[i]);
}
}
// Pop operators from operators stack until it is empty and add result
// of each pop operation in operands stack.
while (!ops.empty()) {
string op1 = oz.top(); oz.pop();
string op2 = oz.top(); oz.pop();

char op = ops.top();ops.pop();

string tmp = op + op2 + op1;


oz.push(tmp);
}
// Final prefix expression is present in operands stack.
return oz.top();
}
int main(){
cin>>expr;
cout<<"Se transforma expresia PostFix: "<<expr<<"\nIn forma PreFix: "<< infixToPrefix(expr);
return 0;
}

pag. 17
Prefix to Infix
Computers usually does the computation in either prefix or postfix (usually postfix). But for
humans, its easier to understand an Infix expression rather than a prefix. Hence conversion is need for
human understanding.
Examples:
Prefix: *+AB-CD Prefix: *-A/BC-/AKL
Infix: ((A+B)*(C-D)) Infix: ((A-(B/C))*((A/K)-L))

Algorithm
1. Read the Prefix expression in reverse order (from right to left)
2. If the symbol is an operand, then push it onto the Stack
3. If the symbol is an operator, then pop two operands from the Stack
3.1. Create a string by concatenating the two operands and the operator between them.
string = (operand1 + operator + operand2)
3.2. And push the resultant string back to Stack
4. Repeat the above steps until end of Prefix expression.

Implementation
// CPP Program to convert prefix to Infix
#include <iostream> #include <stack>
using namespace std;
string expr;//forma prefix
bool isOperator(char x) {
switch (x) {
case '+':
case '-':
case '/':
case '*':
return true;
}
return false;
}
string preToInfix(string pre_s) {
stack<string> st;
// reading from right to left
for (int i = pre_s.size() - 1; i >= 0; i--) {
// check if symbol is operator
if (isOperator(pre_s[i])) { // pop two operands from stack
string op1 = st.top(); st.pop();
string op2 = st.top(); st.pop();
// concat the operands and operator
string temp = "(" + op1 + pre_s[i] + op2 + ")";
st.push(temp); // Push string temp back to stack
}// if symbol is an operand
else {// push the operand to the stack
st.push(string(1, pre_s[i]));
}
}
return st.top();// Stack now contains the Infix expression
}
int main() {
cin>>expr;
cout<<"Se transforma expresia PreFix: "<<expr<<"\nIn forma PostFix: "<< preToInfix(expr);
return 0;
}
pag. 18
Prefix to Postfix
Conversion of Prefix expression directly to Postfix without going through the process of
converting them first to Infix and then to Postfix is much better in terms of computation and better
understanding the expression (Computers evaluate using Postfix expression).
Examples:
Prefix: *+AB-CD Prefix: *-A/BC-/AKL
Postfix: AB+CD-* Postfix: ABC/-AK/L-*
Explanation: Explanation:
Prefix to Infix : (A+B) * (C-D) Prefix to Infix : A-(B/C)*(A/K)-L
Infix to Postfix : AB+CD-* Infix to Postfix : ABC/-AK/L-*

Algorithm
1. Read the Prefix expression in reverse order (from right to left)
2. If the symbol is an operand, then push it onto the Stack
3. If the symbol is an operator, then pop two operands from the Stack
3.1. Create a string by concatenating the two operands and the operator after them.
string = operand1 + operand2 + operator
3.2. And push the resultant string back to Stack
4. Repeat the above steps until end of Prefix expression.

Implementation
#include <iostream> #include <stack>
using namespace std;
string expr;//forma prefix
bool isOperator(char x) {
switch (x) {
case '+': case '-': case '/': case '*':
return true;
}
return false;
}
string preToPost(string pre_s) {
stack<string> st;
// reading from right to left
for (int i = pre_s.size() - 1; i >= 0; i--) {
if (isOperator(pre_s[i])) {// check if symbol is operator
// pop two operands from stack
string op1 = st.top(); st.pop();
string op2 = st.top(); st.pop();
string temp = op1 + op2 + pre_s[i]; //concat the operands and operator
st.push(temp); // Push string temp back to stack
}// if symbol is an operand
else { // push the operand to the stack
st.push(string(1, pre_s[i]));
}
}
return st.top();// stack contains only the Postfix expression
}
int main() {
cin>>expr;
cout<<"Se transforma expresia PreFix: "<<expr<<"\nIn forma PostFix: "<< preToPost(expr);
return 0;
}

pag. 19
Find all possible outcomes of a given expression
Given an arithmetic expression, find all possible outcomes of this expression. Different outcomes
are evaluated by putting brackets at different places.
We may assume that the numbers are single digit numbers in given expression.
Examples:
Input: 1+3*2 Input: 1*2+3*4
Output: 8 7 Output: 14 20 14 20 20
Explanation (1*(2+(3*4))) = 14
(1 + 3)*2 = 80 (1*((2+3)*4)) = 20
(1 + (3 * 2)) = 70 ((1*2)+(3*4)) = 14
((1*(2+3))*4) = 20
((1*2)+3)*4) = 20

The idea is to iterate through every operator in given expression. For every operator, evaluate all
possible values of its left and right sides. Apply current operator on every pair of left side and right side
values and add all evaluated values to the result.

Algorithm
1. Initialize result 'res' as empty.
2. Do following for every operator 'x'.
2.1. Recursively evaluate all possible values on left of 'x'. Let the list of values be 'left'.
2.2. Recursively evaluate all possible values on right of 'x'. Let the list of values be 'right'.
2.3. Loop through all values in list 'left', loop through all values in list 'right'. Apply current
operator 'x' on current items of 'left' and 'right' and add the evaluated value to 'res'.
3. Return 'res'.

Implementation

#include<bits/stdc++.h>
using namespace std;
string expr;//forma infix
void afis(vector<int>v,int n){
for (int i=0; i< v.size(); i++)
cout << v[i] << " ";
cout<<endl;
}
int eval(int a, char op, int b){
if (op=='+') return a+b;
if (op=='-') return a-b;
if (op == '*') return a*b;
}
vector<int> evaluateAll(string expr, int low, int high){
cout<<"st= "<<low<<" dr= "<<high<<endl;
vector<int> res;//vector de raspunsuri
// Un singur caracter, el nu poate fi decat o cifra sau operand, o returnam
if (low == high){
res.push_back(expr[low] - '0');
return res;
}
// daca sunt 3 caractere, cel din mijloc este operatorul
if (low == (high-2)){
int num = eval(expr[low]-'0', expr[low+1],expr[low+2]-'0');
res.push_back(num);
return res;
pag. 20
}
// every i refers to an operator
for (int i=low+1; i<=high; i+=2){
// l retine toate valorile posibile din partea stanga a operatorului 'expr[i]'
vector<int> l = evaluateAll(expr, low, i-1);
// r retine toate valorile posibile din partea dreapta a operatorului 'expr[i]'
vector<int> r = evaluateAll(expr, i+1, high);
cout<<"Vector stanga:";afis(l,l.size());
cout<<"Vector dreapta:";afis(r,r.size());
// Iteram peste valorile obtinute din stanga lui i
for (int s1=0; s1<l.size(); s1++){
// Iteram peste valorile obtinute din dreapta lui i
for (int s2=0; s2<r.size(); s2++){
// Calculam valorile pentru fiecare pereche si adaugam in rezultat
int val = eval(l[s1], expr[i], r[s2]);
res.push_back(val);
}
}
}
//cout<<"Vector rez:";afis(res,res.size());
return res;
}
int main(){
string expr;
cin>>expr;
//raspunsurile le memorez intr-un vector
vector<int> ans = evaluateAll(expr, 0, expr.length()-1);
for (int i=0; i< ans.size(); i++)
cout << ans[i] << endl;
return 0;
}

Exercise:
Extend the above solution so that it works for numbers with multiple digits also. For example,
expressions like “100*30+20” (Hint: We can create an integer array to store all operands and operators of
given expression).
Implementation
………..

pag. 21
pag. 22
Evaluate a boolean expression represented as string
Given a string consisting of only 0, 1, A, B, C where:
A = AND
B = OR
C = XOR
Calculate the value of the string assuming no order of precedence and evaluation is done from left
to right. Constraints – The length of string will be odd. It will always be a valid string. Example, 1AA0
will not be given as an input.(Source : Microsoft online round for internship 2017)
Examples:

Input: 1A0B1 Input: 1C1B1B0A0


Output: 1 (1 AND 0 OR 1 = 1) Output: 0

The idea is to traverse all operands by jumping a character after every iteration. For current
operand str[i], check values of str[i+1] and str[i+2], accordingly decide the value of current
subexpression.
Implementation
#include <bits/stdc++.h>
using namespace std;
string expr;
int evaluateBoolExpr(string s){
// Traverse all operands by jumping a character after every iteration.
for (int i = 0; i < s.length(); i += 2) {
// If operator next to current operand is AND.
if (s[i + 1] == 'A') {
if (s[i + 2] == '0'|| s[i] == '0')
s[i + 2] = '0';
else
s[i + 2] = '1';
}
// If operator next to current operand is OR.
else if (s[i + 1] == 'B') {
if (s[i + 2] == '1'|| s[i] == '1')
s[i + 2] = '1';
else
s[i + 2] = '0';
}
// If operator next to current operand is XOR (Assuming a valid input)
else {
if (s[i + 2] == s[i])
s[i + 2] = '0';
else
s[i + 2] = '1';
}
}
return s[ s.length() - 1] -'0';
}
int main(){
cin>>expr;
cout << evaluateBoolExpr(expr);
return 0;
}

pag. 23

You might also like