Skip to content

refactor: simplify StackPostfixNotation.postfixEvaluate #4264

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 26, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 43 additions & 20 deletions src/main/java/com/thealgorithms/others/StackPostfixNotation.java
Original file line number Diff line number Diff line change
Expand Up @@ -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<Integer> s = new Stack<Integer>();
private static BiFunction<Integer, Integer, Integer> 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<Integer> 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<Integer> 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<Integer> s = new Stack<Integer>();
consumeExpression(s, exp);
if (s.size() != 1) {
throw new IllegalArgumentException("exp is not a proper postfix expression.");
}
Expand Down