diff --git a/src/main/java/com/thealgorithms/others/StackPostfixNotation.java b/src/main/java/com/thealgorithms/others/StackPostfixNotation.java index f8591510e9dc..0e8ad58c41b3 100644 --- a/src/main/java/com/thealgorithms/others/StackPostfixNotation.java +++ b/src/main/java/com/thealgorithms/others/StackPostfixNotation.java @@ -2,38 +2,61 @@ import java.util.Scanner; import java.util.Stack; +import java.util.function.BiFunction; +/** + * @brief Utility class evaluating postix expressions, cf. https://en.wikipedia.org/wiki/Reverse_Polish_notation + * @details The computation is done using Integers. + */ public final class StackPostfixNotation { private StackPostfixNotation() { } - // Evaluates the given postfix expression string and returns the result. - public static int postfixEvaluate(final String exp) { - Stack s = new Stack(); + private static BiFunction getOperator(final String operationSymbol) { + // note the order of operands + switch (operationSymbol) { + case "+": + return (a, b) -> b + a; + case "-": + return (a, b) -> b - a; + case "*": + return (a, b) -> b * a; + case "/": + return (a, b) -> b / a; + default: + throw new IllegalArgumentException("exp contains an unknown operation."); + } + } + + private static void performOperation(Stack s, final String operationSymbol) { + if (s.size() < 2) { + throw new IllegalArgumentException("exp is not a proper postfix expression (too few arguments)."); + } + s.push(getOperator(operationSymbol).apply(s.pop(), s.pop())); + } + + private static void consumeExpression(Stack s, final String exp) { Scanner tokens = new Scanner(exp); while (tokens.hasNext()) { if (tokens.hasNextInt()) { - s.push(tokens.nextInt()); // If int then push to stack - } else { // else pop top two values and perform the operation - if (s.size() < 2) { - throw new IllegalArgumentException("exp is not a proper postfix expression (too few arguments)."); - } - int num2 = s.pop(); - int num1 = s.pop(); - String op = tokens.next(); - - switch (op) { - case "+" -> s.push(num1 + num2); - case "-" -> s.push(num1 - num2); - case "*" -> s.push(num1 * num2); - case "/" -> s.push(num1 / num2); - default -> throw new IllegalArgumentException("exp contains an unknown operation."); - } - // "+", "-", "*", "/" + s.push(tokens.nextInt()); + } else { + performOperation(s, tokens.next()); } } tokens.close(); + } + + /** + * @brief Evaluates the given postfix expression. + * @param exp the expression to evaluate. + * @return the value of the given expression. + * @exception IllegalArgumentException exp is not a valid postix expression. + */ + public static int postfixEvaluate(final String exp) { + Stack s = new Stack(); + consumeExpression(s, exp); if (s.size() != 1) { throw new IllegalArgumentException("exp is not a proper postfix expression."); }