Created
March 28, 2018 19:06
-
-
Save andylshort/4fcd455fdf9fda0d1070373bb2149b46 to your computer and use it in GitHub Desktop.
Simple Reverse Polish Notation Implementation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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