Skip to content

Commit 7590d82

Browse files
refactor: add JavaDocs and improve readability in InfixToPrefix (TheAlgorithms#6363)
* refactor: add JavaDocs and improve readability in InfixToPrefix * formatting: remove redundant newline --------- Co-authored-by: Deniz Altunkapan <[email protected]>
1 parent acb4753 commit 7590d82

File tree

2 files changed

+66
-42
lines changed

2 files changed

+66
-42
lines changed

src/main/java/com/thealgorithms/stacks/InfixToPrefix.java

Lines changed: 65 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -4,85 +4,109 @@
44
import java.util.regex.Matcher;
55
import java.util.regex.Pattern;
66

7+
/**
8+
* Utility class for converting an infix arithmetic expression
9+
* into its equivalent prefix notation expression.
10+
* <p>
11+
* This class provides a static method to perform the conversion,
12+
* validating balanced brackets before processing.
13+
* </p>
14+
*/
715
public final class InfixToPrefix {
16+
817
private InfixToPrefix() {
918
}
1019

1120
/**
12-
* Convert an infix expression to a prefix expression using stack.
21+
* Converts a given infix expression string to a prefix expression string.
22+
* <p>
23+
* The method validates that the input expression has balanced brackets using
24+
* {@code BalancedBrackets.isBalanced} on the filtered bracket characters.
25+
* It throws an {@code IllegalArgumentException} if the brackets are unbalanced,
26+
* and a {@code NullPointerException} if the input is null.
27+
* </p>
28+
* <p>
29+
* Supported operators: {@code +, -, *, /, ^} and operands can be letters or digits.
30+
* </p>
1331
*
14-
* @param infixExpression the infix expression to convert
15-
* @return the prefix expression
16-
* @throws IllegalArgumentException if the infix expression has unbalanced brackets
17-
* @throws NullPointerException if the infix expression is null
32+
* @param infixExpression the arithmetic expression in infix notation
33+
* @return the equivalent prefix notation expression
34+
* @throws IllegalArgumentException if brackets are unbalanced
35+
* @throws NullPointerException if the input expression is null
1836
*/
19-
public static String infix2Prefix(String infixExpression) throws IllegalArgumentException {
37+
public static String infix2Prefix(String infixExpression) {
2038
if (infixExpression == null) {
2139
throw new NullPointerException("Input expression cannot be null.");
2240
}
41+
2342
infixExpression = infixExpression.trim();
2443
if (infixExpression.isEmpty()) {
2544
return "";
2645
}
46+
2747
if (!BalancedBrackets.isBalanced(filterBrackets(infixExpression))) {
2848
throw new IllegalArgumentException("Invalid expression: unbalanced brackets.");
2949
}
3050

3151
StringBuilder output = new StringBuilder();
32-
Stack<Character> stack = new Stack<>();
33-
// Reverse the infix expression for prefix conversion
52+
Stack<Character> operatorStack = new Stack<>();
53+
54+
// Reverse the infix expression to facilitate prefix conversion
3455
String reversedInfix = new StringBuilder(infixExpression).reverse().toString();
35-
for (char element : reversedInfix.toCharArray()) {
36-
if (Character.isLetterOrDigit(element)) {
37-
output.append(element);
38-
} else if (element == ')') {
39-
stack.push(element);
40-
} else if (element == '(') {
41-
while (!stack.isEmpty() && stack.peek() != ')') {
42-
output.append(stack.pop());
56+
57+
for (char token : reversedInfix.toCharArray()) {
58+
if (Character.isLetterOrDigit(token)) {
59+
// Append operands directly to output
60+
output.append(token);
61+
} else if (token == ')') {
62+
// Push ')' onto stack (since expression is reversed, '(' and ')' roles swapped)
63+
operatorStack.push(token);
64+
} else if (token == '(') {
65+
// Pop operators until ')' is found
66+
while (!operatorStack.isEmpty() && operatorStack.peek() != ')') {
67+
output.append(operatorStack.pop());
4368
}
44-
stack.pop();
69+
operatorStack.pop(); // Remove the ')'
4570
} else {
46-
while (!stack.isEmpty() && precedence(element) < precedence(stack.peek())) {
47-
output.append(stack.pop());
71+
// Pop operators with higher precedence before pushing current operator
72+
while (!operatorStack.isEmpty() && precedence(token) < precedence(operatorStack.peek())) {
73+
output.append(operatorStack.pop());
4874
}
49-
stack.push(element);
75+
operatorStack.push(token);
5076
}
5177
}
52-
while (!stack.isEmpty()) {
53-
output.append(stack.pop());
78+
79+
// Append any remaining operators in stack
80+
while (!operatorStack.isEmpty()) {
81+
output.append(operatorStack.pop());
5482
}
5583

56-
// Reverse the result to get the prefix expression
84+
// Reverse the output to obtain the final prefix expression
5785
return output.reverse().toString();
5886
}
5987

6088
/**
61-
* Determines the precedence of an operator.
89+
* Returns the precedence level of the given operator.
6290
*
63-
* @param operator the operator whose precedence is to be determined
64-
* @return the precedence of the operator
91+
* @param operator the operator character (e.g., '+', '-', '*', '/', '^')
92+
* @return the precedence value: higher means higher precedence,
93+
* or -1 if the character is not a recognized operator
6594
*/
6695
private static int precedence(char operator) {
67-
switch (operator) {
68-
case '+':
69-
case '-':
70-
return 0;
71-
case '*':
72-
case '/':
73-
return 1;
74-
case '^':
75-
return 2;
76-
default:
77-
return -1;
78-
}
96+
return switch (operator) {
97+
case '+', '-' -> 0;
98+
case '*', '/' -> 1;
99+
case '^' -> 2;
100+
default -> -1;
101+
};
79102
}
80103

81104
/**
82-
* Filters out all characters from the input string except brackets.
105+
* Extracts only the bracket characters from the input string.
106+
* Supports parentheses (), curly braces {}, square brackets [], and angle brackets &lt;&gt;.
83107
*
84-
* @param input the input string to filter
85-
* @return a string containing only brackets from the input string
108+
* @param input the original expression string
109+
* @return a string containing only bracket characters from the input
86110
*/
87111
private static String filterBrackets(String input) {
88112
Pattern pattern = Pattern.compile("[^(){}\\[\\]<>]");

src/test/java/com/thealgorithms/stacks/InfixToPrefixTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ public class InfixToPrefixTest {
1313

1414
@ParameterizedTest
1515
@MethodSource("provideValidExpressions")
16-
void testValidExpressions(String infix, String expectedPrefix) throws Exception {
16+
void testValidExpressions(String infix, String expectedPrefix) {
1717
assertEquals(expectedPrefix, InfixToPrefix.infix2Prefix(infix));
1818
}
1919

0 commit comments

Comments
 (0)