Skip to content

Commit bdc0b3f

Browse files
committed
Add Infix To Prefix new algorithm
1 parent 842ff52 commit bdc0b3f

File tree

2 files changed

+124
-0
lines changed

2 files changed

+124
-0
lines changed
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package com.thealgorithms.stacks;
2+
3+
import java.util.Stack;
4+
import java.util.regex.Matcher;
5+
import java.util.regex.Pattern;
6+
7+
public final class InfixToPrefix {
8+
private InfixToPrefix() {
9+
}
10+
11+
/**
12+
* Converts an infix expression to a prefix expression.
13+
*
14+
* @param infixExpression the infix expression to convert
15+
* @return the prefix expression
16+
* @throws Exception if the infix expression has unbalanced brackets
17+
*/
18+
public static String infix2Prefix(String infixExpression) throws Exception {
19+
if (!BalancedBrackets.isBalanced(filterBrackets(infixExpression))) {
20+
throw new Exception("invalid expression");
21+
}
22+
StringBuilder output = new StringBuilder();
23+
Stack<Character> stack = new Stack<>();
24+
// Reverse the infix expression for prefix conversion
25+
String reversedInfix = new StringBuilder(infixExpression).reverse().toString();
26+
for (char element : reversedInfix.toCharArray()) {
27+
if (Character.isLetterOrDigit(element)) {
28+
output.append(element);
29+
} else if (element == ')') {
30+
stack.push(element);
31+
} else if (element == '(') {
32+
while (!stack.isEmpty() && stack.peek() != ')') {
33+
output.append(stack.pop());
34+
}
35+
stack.pop();
36+
} else {
37+
while (!stack.isEmpty() && precedence(element) < precedence(stack.peek())) {
38+
output.append(stack.pop());
39+
}
40+
stack.push(element);
41+
}
42+
}
43+
while (!stack.isEmpty()) {
44+
output.append(stack.pop());
45+
}
46+
47+
// Reverse the result to get the prefix expression
48+
return output.reverse().toString();
49+
}
50+
51+
/**
52+
* Determines the precedence of an operator.
53+
*
54+
* @param operator the operator whose precedence is to be determined
55+
* @return the precedence of the operator
56+
*/
57+
private static int precedence(char operator) {
58+
switch (operator) {
59+
case '+':
60+
case '-':
61+
return 0;
62+
case '*':
63+
case '/':
64+
return 1;
65+
case '^':
66+
return 2;
67+
default:
68+
return -1;
69+
}
70+
}
71+
72+
/**
73+
* Filters out all characters from the input string except brackets.
74+
*
75+
* @param input the input string to filter
76+
* @return a string containing only brackets from the input string
77+
*/
78+
private static String filterBrackets(String input) {
79+
Pattern pattern = Pattern.compile("[^(){}\\[\\]<>]");
80+
Matcher matcher = pattern.matcher(input);
81+
return matcher.replaceAll("");
82+
}
83+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package com.thealgorithms.stacks;
2+
3+
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
import static org.junit.jupiter.api.Assertions.assertThrows;
5+
6+
import java.util.stream.Stream;
7+
import org.junit.jupiter.params.ParameterizedTest;
8+
import org.junit.jupiter.params.provider.Arguments;
9+
import org.junit.jupiter.params.provider.MethodSource;
10+
11+
public class InfixToPrefixTest {
12+
13+
@ParameterizedTest
14+
@MethodSource("provideValidExpressions")
15+
void testValidExpressions(String infix, String expectedPrefix) throws Exception {
16+
assertEquals(expectedPrefix, InfixToPrefix.infix2Prefix(infix));
17+
}
18+
19+
private static Stream<Arguments> provideValidExpressions() {
20+
return Stream.of(
21+
Arguments.of("3+2", "+32"), // Simple addition
22+
Arguments.of("1+(2+3)", "+1+23"), // Parentheses
23+
Arguments.of("(3+4)*5-6", "-*+3456"), // Nested operations
24+
Arguments.of("a+b*c", "+a*bc") // Multiplication precedence
25+
);
26+
}
27+
28+
@ParameterizedTest
29+
@MethodSource("provideInvalidExpressions")
30+
void testInvalidExpressions(String infix, String expectedMessage) {
31+
Exception exception = assertThrows(Exception.class, () -> InfixToPrefix.infix2Prefix(infix));
32+
assertEquals(expectedMessage, exception.getMessage());
33+
}
34+
35+
private static Stream<Arguments> provideInvalidExpressions() {
36+
return Stream.of(
37+
Arguments.of("((a+b)*c-d", "invalid expression"), // Missing closing bracket
38+
Arguments.of("a++b", "invalid expression") // Invalid operator
39+
);
40+
}
41+
}

0 commit comments

Comments
 (0)