Skip to content

Instantly share code, notes, and snippets.

@andylshort
Created March 28, 2018 19:06
Show Gist options
  • Save andylshort/4fcd455fdf9fda0d1070373bb2149b46 to your computer and use it in GitHub Desktop.
Save andylshort/4fcd455fdf9fda0d1070373bb2149b46 to your computer and use it in GitHub Desktop.
Simple Reverse Polish Notation Implementation
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.List;
import java.util.Stack;
public class ReversePolish {
private ReversePolish() { }
public static Double solve(String equation) {
return solve(toPostFix(equation));
}
public static Double solve(String[] tokens) {
Stack<Double> stack = new Stack<Double>();
Deque<String> queue = new ArrayDeque<String>();
for (String token : tokens) {
queue.addLast(token);
}
while (true) {
String token = queue.pollFirst();
boolean lastToken = queue.size() == 0;
double a = 0, b = 0;
switch (token) {
case "+":
b = stack.pop();
a = stack.pop();
double addition = a + b;
queue.addFirst(String.valueOf(addition));
break;
case "-":
b = stack.pop();
a = stack.pop();
double subtraction = a - b;
queue.addFirst(String.valueOf(subtraction));
break;
case "*":
b = stack.pop();
a = stack.pop();
double multiplication = a * b;
queue.addFirst(String.valueOf(multiplication));
break;
case "/":
b = stack.pop();
a = stack.pop();
double division = a / b;
queue.addFirst(String.valueOf(division));
break;
case "^":
b = stack.pop();
a = stack.pop();
double power = Math.pow(a, b);
queue.addFirst(String.valueOf(power));
break;
case "sin":
a = stack.pop();
double sin = Math.sin(a);
queue.addFirst(String.valueOf(sin));
break;
case "cos":
a = stack.pop();
double cos = Math.cos(a);
queue.addFirst(String.valueOf(cos));
break;
case "tan":
a = stack.pop();
double tan = Math.tan(a);
queue.addFirst(String.valueOf(tan));
break;
case "sqrt":
a = stack.pop();
double sqrt = Math.sqrt(a);
queue.addFirst(String.valueOf(sqrt));
break;
case "ln":
a = stack.pop();
double ln = Math.log1p(a);
queue.addFirst(String.valueOf(ln));
break;
case "pi":
stack.push(Math.PI);
break;
case "e":
stack.push(Math.PI);
break;
default:
a = Double.parseDouble(token);
stack.push(a);
break;
}
if (lastToken) {
while (!stack.isEmpty()) {
queue.addLast(String.valueOf(stack.pop()));
}
return Double.parseDouble(queue.pollFirst());
}
}
}
public static String[] toPostFix(String equation) {
Stack<String> stack = new Stack<String>();
Deque<String> queue = new ArrayDeque<String>();
List<String> result = new ArrayList<String>();
String[] tokens = equation.split(" ");
for (String token : tokens) {
queue.addLast(token);
}
while (true) {
String token = queue.pollFirst();
boolean lastToken = queue.size() == 0;
switch (token) {
case "+":
case "-":
case "*":
case "/":
case "^":
while (!stack.isEmpty()) {
if (stack.peek().equals("(")) {
break;
} else {
String currentOp = stack.peek();
int tokenPrec = getPrecedence(token);
int currentOpPrec = getPrecedence(currentOp);
if (currentOpPrec >= tokenPrec) {
result.add(stack.pop());
}
}
}
stack.push(token);
break;
case "sin":
case "cos":
case "tan":
case "sqrt":
stack.push(token);
break;
case "(":
stack.push(token);
break;
case ")":
while (!stack.isEmpty()) {
String popped = stack.pop();
if (popped.equals("(")) {
break;
} else {
result.add(popped);
}
}
break;
default:
result.add(token);
break;
}
if (lastToken) {
while (!stack.isEmpty()) {
result.add(stack.pop());
}
break;
}
}
return result.toArray(new String[result.size()]);
}
private static int getPrecedence(String operator) {
switch (operator) {
case "+":
case "-":
return 1;
case "*":
case "/":
return 2;
default:
return 3;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment