Skip to content

Commit 34c3797

Browse files
committed
Day-37: Infix to postfix converter
1 parent 6032297 commit 34c3797

File tree

2 files changed

+210
-3
lines changed

2 files changed

+210
-3
lines changed

README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44

55
| Current Status| Stats |
66
| :------------: | :----------: |
7-
| Total Problems | 56 |
8-
| Current Streak | 36 |
9-
| Longest Streak | 36 ( August 17, 2015 - September 21, 2015 ) |
7+
| Total Problems | 57 |
8+
| Current Streak | 37 |
9+
| Longest Streak | 37 ( August 17, 2015 - September 22, 2015 ) |
1010

1111
</center>
1212

@@ -100,6 +100,7 @@ Include contains single header implementation of data structures and some algori
100100
| Problem | Solution |
101101
| :------------ | :----------: |
102102
| We have series of n daily price quotes for a stock. We need to calculate span of stock's price for all n days. Span for ith day is defined as maximum number of consecutive days, for which the price of the stock was less than or equal to ith day. For stock quotes {100, 60, 70, 65, 80, 85} span will be {1, 1, 2, 1, 4, 5}. Span for day 1 is always 1, now for day 2 stock is at 60, and there is no day befor it when stock was less than 60. So span remains 1. For day 3, the stock is priced at 70, so its span is 2, as previous day it was 60, and so on. | [stock_span_problem.cpp](stack_problems/stock_span_problem.cpp) |
103+
| Given an infix expression, convert it to postfix expression, Example (A+B)\*C --> AB+C\* | [infix_to_postfix.cpp](stack_problems/infix_to_postfix.cpp) |
103104

104105
### Sort and Search Problems
105106
| Problem | Solution |

stack_problems/infix_to_postfix.cpp

Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
/**
2+
* Given an infix expression, convert it to postfix. Consider usual operator precedence.
3+
* Consider only following operands in your arsenal.
4+
* +, -, * , /, ^(power)
5+
* Operands are only alphabets --> 'a '-->'z' and 'A'-->'Z'
6+
* Another assumption is operand is a single char.
7+
*/
8+
9+
#include <iostream>
10+
#include <stack.h>
11+
#include <string>
12+
13+
// all utility and main functions declared first
14+
/**
15+
* isOperator- Determines if input char is operator
16+
* @param c - char
17+
* @return - true or false
18+
*/
19+
bool isOperator( char c );
20+
21+
/**
22+
* isOperand Determines if input char is operand
23+
* @param c - char
24+
* @return true or false.
25+
*/
26+
bool isOperand( char c );
27+
28+
29+
/**
30+
* getOperatorWeight returns an integer weight of the operator
31+
* @param c - An operator
32+
* @return Weight of operator , larger is more precedence
33+
*/
34+
int getOperatorWeight(char c);
35+
36+
37+
/**
38+
* isRightAssociative -Determines if operator is right associative.
39+
* @param c operator
40+
* @return returns true if operator is right associative
41+
*
42+
* Associativity only comes to picture when both operators have same weight
43+
* Example ^ is right associative ( ^ represents power of)
44+
* 5 ^ 4 ^ 3 ^ 2 = 5 ^ ( 4 ^ ( 3 ^ 2 ) )
45+
* where as 7 − 4 + 2 (7 − 4) + 2 = 5 or 7 − (4 + 2) = 1
46+
*/
47+
bool isRightAssociative(char c);
48+
49+
/**
50+
* [hasHigherPrecedence] compare op1 and op2 based on precedence
51+
* @param op1 operaror 1
52+
* @param op2 operator 2
53+
* @return return true if precedence(op1) > precedence(op2), else false
54+
*/
55+
bool hasHigherPrecedence(char op1, char op2);
56+
57+
/**
58+
* [infixToPostfix - converts infix expr to postfix expr
59+
* @param expression - infix expre
60+
* @return postfix expr
61+
*/
62+
std::string infixToPostfix( std::string expression );
63+
64+
65+
//check if c is an operator
66+
bool isOperator( char c )
67+
{
68+
if ( c == '+' || c == '-' || c == '*' || c == '/' || c == '^') {
69+
return true;
70+
}
71+
return false;
72+
}
73+
74+
//check if c is a valid operand defined in comments.
75+
bool isOperand( char c )
76+
{
77+
if ( c >= 'a' && c <= 'z' ) return true;
78+
if ( c >= 'A' && c <= 'Z' ) return true;
79+
return false;
80+
}
81+
82+
//returns precedence weight of the char c.
83+
// more weight higher precedence.
84+
int getOperatorWeight( char c )
85+
{
86+
int weight;
87+
switch(c) {
88+
case '+':
89+
case '-':
90+
weight = 1;
91+
break;
92+
case '*':
93+
case '/':
94+
weight = 2;
95+
break;
96+
case '^':
97+
weight = 3;
98+
break;
99+
default:
100+
weight = -1;
101+
}
102+
return weight;
103+
}
104+
105+
106+
// is operator right associative?
107+
bool isRightAssociative( char op )
108+
{
109+
if ( op == '^') return true;
110+
return false;
111+
}
112+
113+
bool hasHigherPrecedence( char op1, char op2 )
114+
{
115+
// get weight of the operators
116+
int w1 = getOperatorWeight(op1);
117+
int w2 = getOperatorWeight(op2);
118+
119+
// If both operators weigh same, return true if operators are
120+
// left associative, return false if right associative.
121+
if ( w1 == w2 ) {
122+
if ( isRightAssociative(op1) ) {
123+
return false;
124+
}
125+
return true;
126+
}
127+
return w1 > w2 ? true : false;
128+
}
129+
130+
// final function to convert infix to postix operator.
131+
132+
std::string infixToPostFix(std::string expr)
133+
{
134+
bool errorDetected = false;
135+
algo::Stack<char> operatorStack;
136+
std::string postFixExpr = "";
137+
138+
//scanning input infix expr left to right char by char
139+
for ( char c : expr ) {
140+
141+
// char is delimiter, continue
142+
if ( c == ',' || c == ' ') {
143+
continue;
144+
}
145+
146+
//if character is an operand
147+
else if ( isOperand(c) ) {
148+
postFixExpr += c;
149+
}
150+
151+
//if character is operator
152+
else if ( isOperator(c) ) {
153+
//if stack is not empty pop the stack back and compare precedence.
154+
//if higher precedence perform operation.
155+
while ( !operatorStack.empty() && operatorStack.top() != '(' &&
156+
hasHigherPrecedence(operatorStack.top(), c) ) {
157+
postFixExpr += operatorStack.top();
158+
operatorStack.pop();
159+
}
160+
operatorStack.push(c);
161+
}
162+
163+
else if( c == '(' ) {
164+
operatorStack.push(c);
165+
}
166+
167+
else if( c == ')' ) {
168+
while( !operatorStack.empty() && operatorStack.top() != '(' ) {
169+
postFixExpr += operatorStack.top();
170+
operatorStack.pop();
171+
}
172+
operatorStack.pop();
173+
}
174+
175+
else {
176+
std::cout << " ERROR An invalid operator/operand detected\n";
177+
errorDetected = true;
178+
break;
179+
}
180+
}
181+
if (errorDetected) {
182+
return "INVALID EXPR!";
183+
}
184+
185+
while( !operatorStack.empty() ) {
186+
postFixExpr += operatorStack.top();
187+
operatorStack.pop();
188+
}
189+
return postFixExpr;
190+
}
191+
192+
193+
int main()
194+
{
195+
std::string expr;
196+
std::cout << "Provide an expression such that :"
197+
<< "1. Expression shoule be parenthesis valid.\n"
198+
<< "2. Operators should contain +, -, /, *, ^\n"
199+
<< "3. Operands should contain A-Z or a-z \n"
200+
<< "Your expression is :";
201+
std::getline(std::cin, expr);
202+
std::cout << "Corresponding postfix expression of the express - "
203+
<< expr
204+
<< " is :" << infixToPostFix(expr) << std::endl;
205+
return 0;
206+
}

0 commit comments

Comments
 (0)