diff --git a/src/main/java/com/thealgorithms/stacks/InfixToPostfix.java b/src/main/java/com/thealgorithms/stacks/InfixToPostfix.java
index 33611bd73dba..77ca3e70849f 100644
--- a/src/main/java/com/thealgorithms/stacks/InfixToPostfix.java
+++ b/src/main/java/com/thealgorithms/stacks/InfixToPostfix.java
@@ -4,54 +4,96 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+/**
+ * Utility class for converting an infix arithmetic expression
+ * into its equivalent postfix (Reverse Polish Notation) form.
+ *
+ * This class provides a static method to perform the conversion,
+ * validating balanced brackets before processing.
+ *
+ */
public final class InfixToPostfix {
+
private InfixToPostfix() {
}
- public static String infix2PostFix(String infixExpression) throws Exception {
+ /**
+ * Converts a given infix expression string to a postfix expression string.
+ *
+ * The method first checks if the brackets in the input expression are balanced
+ * by calling {@code BalancedBrackets.isBalanced} on the filtered brackets.
+ * If the brackets are not balanced, it throws an IllegalArgumentException.
+ *
+ *
+ * Supported operators are: {@code +, -, *, /, ^}
+ * and operands can be letters or digits.
+ *
+ *
+ * @param infixExpression the arithmetic expression in infix notation
+ * @return the equivalent postfix notation expression
+ * @throws IllegalArgumentException if the brackets in the expression are unbalanced
+ */
+ public static String infix2PostFix(String infixExpression) {
if (!BalancedBrackets.isBalanced(filterBrackets(infixExpression))) {
- throw new Exception("invalid expression");
+ throw new IllegalArgumentException("Invalid expression: unbalanced brackets.");
}
+
StringBuilder output = new StringBuilder();
- Stack stack = new Stack<>();
- for (char element : infixExpression.toCharArray()) {
- if (Character.isLetterOrDigit(element)) {
- output.append(element);
- } else if (element == '(') {
- stack.push(element);
- } else if (element == ')') {
- while (!stack.isEmpty() && stack.peek() != '(') {
- output.append(stack.pop());
+ Stack operatorStack = new Stack<>();
+
+ for (char token : infixExpression.toCharArray()) {
+ if (Character.isLetterOrDigit(token)) {
+ // Append operands (letters or digits) directly to output
+ output.append(token);
+ } else if (token == '(') {
+ // Push '(' to stack
+ operatorStack.push(token);
+ } else if (token == ')') {
+ // Pop and append until '(' is found
+ while (!operatorStack.isEmpty() && operatorStack.peek() != '(') {
+ output.append(operatorStack.pop());
}
- stack.pop();
+ operatorStack.pop(); // Remove '(' from stack
} else {
- while (!stack.isEmpty() && precedence(element) <= precedence(stack.peek())) {
- output.append(stack.pop());
+ // Pop operators with higher or equal precedence and append them
+ while (!operatorStack.isEmpty() && precedence(token) <= precedence(operatorStack.peek())) {
+ output.append(operatorStack.pop());
}
- stack.push(element);
+ operatorStack.push(token);
}
}
- while (!stack.isEmpty()) {
- output.append(stack.pop());
+
+ // Pop any remaining operators
+ while (!operatorStack.isEmpty()) {
+ output.append(operatorStack.pop());
}
+
return output.toString();
}
+ /**
+ * Returns the precedence level of the given operator.
+ *
+ * @param operator the operator character (e.g., '+', '-', '*', '/', '^')
+ * @return the precedence value: higher means higher precedence,
+ * or -1 if the character is not a recognized operator
+ */
private static int precedence(char operator) {
- switch (operator) {
- case '+':
- case '-':
- return 0;
- case '*':
- case '/':
- return 1;
- case '^':
- return 2;
- default:
- return -1;
- }
+ return switch (operator) {
+ case '+', '-' -> 0;
+ case '*', '/' -> 1;
+ case '^' -> 2;
+ default -> -1;
+ };
}
+ /**
+ * Extracts only the bracket characters from the input string.
+ * Supports parentheses (), curly braces {}, square brackets [], and angle brackets <>.
+ *
+ * @param input the original expression string
+ * @return a string containing only bracket characters from the input
+ */
private static String filterBrackets(String input) {
Pattern pattern = Pattern.compile("[^(){}\\[\\]<>]");
Matcher matcher = pattern.matcher(input);
diff --git a/src/test/java/com/thealgorithms/stacks/InfixToPostfixTest.java b/src/test/java/com/thealgorithms/stacks/InfixToPostfixTest.java
index 02a08e393a00..bd63c1ac28f2 100644
--- a/src/test/java/com/thealgorithms/stacks/InfixToPostfixTest.java
+++ b/src/test/java/com/thealgorithms/stacks/InfixToPostfixTest.java
@@ -12,7 +12,7 @@ class InfixToPostfixTest {
@ParameterizedTest
@MethodSource("provideValidExpressions")
- void testValidExpressions(String infix, String expectedPostfix) throws Exception {
+ void testValidExpressions(String infix, String expectedPostfix) {
assertEquals(expectedPostfix, InfixToPostfix.infix2PostFix(infix));
}
@@ -28,6 +28,6 @@ void testInvalidExpressions(String infix, String expectedMessage) {
}
private static Stream provideInvalidExpressions() {
- return Stream.of(Arguments.of("((a+b)*c-d", "invalid expression"));
+ return Stream.of(Arguments.of("((a+b)*c-d", "Invalid expression: unbalanced brackets."));
}
}