Skip to content

Commit d91814e

Browse files
authored
Shunting Yard Algorithm
shunting yard algorithm calculator, can only accept these symbols: +-/*()^
0 parents  commit d91814e

File tree

1 file changed

+148
-0
lines changed

1 file changed

+148
-0
lines changed

Diff for: Shunting Yard Algorithm

+148
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
#include <iostream>
2+
#include <stack>
3+
#include <string>
4+
#include <cctype>
5+
#include <sstream>
6+
#include <map>
7+
#include <stdexcept>
8+
#include <math.h>
9+
#include <regex>
10+
using namespace std;
11+
stack<string> postfixVec;
12+
stack<string> shuffleVec;
13+
vector<string> postEvaVec;
14+
15+
class classCalc {
16+
public:
17+
classCalc() {
18+
string userInput;
19+
getline(cin, userInput);
20+
cout << userInput << endl;
21+
classCalcBrain(userInput);
22+
evaluatorFunc(postfixVec);
23+
}
24+
int precedence(string op);
25+
void classCalcBrain(string userInput);
26+
void evaluatorFunc (stack<string>& inputStack);
27+
void printStack(stack<string> stack);
28+
double operations(double num1, double num2, char oper);
29+
};
30+
31+
//sets the level of importance according to PEMDAS
32+
int classCalc::precedence(string op) {
33+
if (op == "+" || op == "-") return 1;
34+
if (op == "*" || op == "/") return 2;
35+
if (op == "^") return 3;
36+
else return 0;
37+
}
38+
39+
void classCalc::classCalcBrain(const string userInput) {
40+
stringstream ss(userInput);
41+
string currentToken;
42+
for(auto i = 0; i < userInput.length() + 1; i++) {
43+
char part = userInput[i];
44+
if (isspace(part)) continue;
45+
//pushes and creates tokenized digits
46+
if (isdigit(part) || part == '.') {
47+
currentToken += part;
48+
} else {
49+
if (!currentToken.empty()) {
50+
postfixVec.push(currentToken);
51+
currentToken.clear();
52+
}
53+
}
54+
55+
//what to do when theres parenthesis
56+
if(part == '(') {
57+
string str(1, part);
58+
shuffleVec.push(str);
59+
} else if (part == ')') {
60+
//loop that pushes all symbols onto main when the closing parenthesis is found
61+
while(!shuffleVec.empty() && shuffleVec.top() != "(") {
62+
postfixVec.push(shuffleVec.top());
63+
shuffleVec.pop();
64+
}
65+
if (!shuffleVec.empty()) shuffleVec.pop();
66+
}
67+
68+
//what happens with symbols
69+
if(part == '+' || part == '-' || part == '*' || part == '/' || part == '^') {
70+
string part1(1, part);
71+
//if its empty, it pushes whatever
72+
if (shuffleVec.empty() || precedence(shuffleVec.top()) <= precedence(part1)) {
73+
shuffleVec.push(part1);
74+
} else {
75+
//if its not, precedence comes into play
76+
while (!shuffleVec.empty() && precedence(shuffleVec.top()) >= precedence(part1)) {
77+
postfixVec.push(shuffleVec.top());
78+
shuffleVec.pop();
79+
}
80+
shuffleVec.push(part1);
81+
}
82+
}
83+
84+
85+
86+
}
87+
//after everything, pushes all left overs onto main
88+
if (!currentToken.empty()) postfixVec.push(currentToken);
89+
90+
while(!shuffleVec.empty()) {
91+
postfixVec.push(shuffleVec.top());
92+
shuffleVec.pop();
93+
}
94+
}
95+
96+
97+
void classCalc::evaluatorFunc (stack<string>& inputStack) {
98+
vector<double> numHold;
99+
100+
//pushes everything from the stack onto a vector for better calculation handling
101+
while(!inputStack.empty()) {
102+
postEvaVec.push_back(inputStack.top());
103+
inputStack.pop();
104+
}
105+
106+
for (int i = postEvaVec.size() - 1; i >= 0; i--) {
107+
string token = postEvaVec[i];
108+
109+
//if its a digit, it pushes it onto a vector
110+
if (isdigit(token[0])) {
111+
numHold.push_back(stod(token));
112+
} else {
113+
//if its a symbol, it pops the latest 2 elements and creates them into numerical values
114+
//and the symbol gets converted into a character so it can be used in switch cases
115+
char oper = token[0];
116+
117+
double num2 = numHold.back(); numHold.pop_back();
118+
double num1 = numHold.back(); numHold.pop_back();
119+
120+
double result = operations(num1, num2, oper);
121+
//pushes the result back into the holding vector
122+
numHold.push_back(result);
123+
}
124+
}
125+
//prints the remaining element of the holding vector which is the resultant
126+
cout << "= " << numHold.back() << endl;
127+
}
128+
129+
//does the actual calculations
130+
double classCalc::operations(double num1, double num2, char oper) {
131+
switch(oper) {
132+
case '+': return num1 + num2;
133+
case '-': return num1 - num2;
134+
case '*': return num1 * num2;
135+
case '^': return pow(num1, num2);
136+
case '/': if (num2 == 0) {
137+
cout << "Error - dividing by zeros" << endl; break;
138+
}
139+
else return num1 / num2;
140+
}
141+
}
142+
143+
int main() {
144+
classCalc obj;
145+
}
146+
147+
148+

0 commit comments

Comments
 (0)