-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathInfixToPostfixNew.cpp
156 lines (135 loc) · 3.69 KB
/
InfixToPostfixNew.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#include <iostream>
#include<string>
#include<stack>
#include <cmath>
using namespace std;
bool IsOperator(char token) {
switch (token) {
case '+':
case '-':
case '*':
case '/':
case '(':
case ')':
case '^':
case ' ':
return true;
default:
return false;
}
}
int GetPrecedence(char token) {
if (token == '^')
return 3;
else if (token == '*' || token == '/')
return 2;
else if (token = '+' || token == '-')
return 1;
else
return -1;
}
char Associativity(char token) {
if (token == '^')
return 'r';
}
//Shunting-yard Algorithm
string ConvertInfixToPostfix(string infix) {
stack<char> op;
string output = "";
for (int i = 0; i < infix.length();i++) {
//check if the scanned token is operand?
if (!IsOperator(infix[i])) {
//to handle cases where operands have more than 1 digit
while (!IsOperator(infix[i]) && i < infix.length()) {
output += infix[i];
i++;
}
//Make sure there is a space after each element (both operand and operator).
if (IsOperator(infix[i]) || i == infix.length())
output += ' ';
--i;//Make sure the for loop goes through the entire element
}
//Just need to handle cases where it is an operator
else if (op.empty() || infix[i] == '(' || op.top() == '(')
{
op.push(infix[i]);
}
else if (infix[i] == ')') {
while (op.top() != '(') {
output += op.top();
output += ' ';
op.pop();
}
op.pop();
}
else if (GetPrecedence(infix[i]) > GetPrecedence(op.top()))
{
Perform1: //lable Perform1
op.push(infix[i]);
}
else if (GetPrecedence(infix[i]) <= GetPrecedence(op.top())) {
//If the top of the stack and the scanned operator have equal precedence,
// then if the scanned operator is right-associative, it has higher precedence than
// the top of the stack.
if (Associativity(infix[i]) == 'r')
goto Perform1;
while (!op.empty() && op.top() != '(' && GetPrecedence(op.top()) >= GetPrecedence(infix[i])) {
output += op.top();
output += ' ';
op.pop();
}
op.push(infix[i]);
}
}
while (!op.empty()) {
output += op.top();
output += (op.size() == 1)? "" : " ";
op.pop();
}
return output;
}
int BasicCalculator(int num1, int num2, char op) {
switch (op) {
case '^':
return pow(num2, num1);
case '*':
return num2 * num1;
case '/':
return num2 / num1;
case '+':
return num2 + num1;
case '-':
return num2 - num1;
}
}
int PostfixCalculator(string postfix) {
stack<int> output;
int number = 0;
bool check = false;
for (int i = 0; i < postfix.length();i++) {
if (!IsOperator(postfix[i])) {
number = number * 10 + postfix[i] - '0';
check = true;
}
else if (number > 0 || check) {
output.push(number);
number = 0;
check = false;
}
else if (postfix[i] != ' ')
{
int num1 = output.top();
output.pop();
int num2 = output.top();
output.pop();
output.push(BasicCalculator(num1, num2, postfix[i]));
}
}
return output.top();
}
int main()
{
string s;
cin >> s;
cout << PostfixCalculator(ConvertInfixToPostfix(s)) << endl;
}