-
Notifications
You must be signed in to change notification settings - Fork 20.5k
Add Infix To Prefix
new algorithm with unit tests
#5537
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
Changes from all commits
Commits
Show all changes
22 commits
Select commit
Hold shift + click to select a range
bdc0b3f
Add `Infix To Prefix` new algorithm
Hardvan 6a0d263
Update directory
Hardvan 8a9df01
Merge branch 'master' into infix_to_prefix_new_algo
Hardvan a3eeb1b
Update directory
Hardvan 27c6c0d
Fix clang
Hardvan 6865537
Merge branch 'infix_to_prefix_new_algo' of https://github.com/Hardvan…
Hardvan abf24f2
Fix clang
Hardvan 60c2c24
Add more tests
Hardvan 004735f
Fix comma error
Hardvan a2a0b83
Fix test cases
Hardvan a3c67fe
Fix comment
Hardvan 0f70133
Remove unused import
Hardvan 620cdd1
Merge branch 'master' into infix_to_prefix_new_algo
Hardvan bd35cee
Update directory
Hardvan 24c144f
Add tests for null & empty strings
Hardvan 369293d
Merge branch 'infix_to_prefix_new_algo' of https://github.com/Hardvan…
Hardvan ed73382
Implement suggested changes
Hardvan 9a0e344
Merge branch 'master' into infix_to_prefix_new_algo
alxkm dc5bbcd
Merge branch 'master' into infix_to_prefix_new_algo
Hardvan 8aecb2e
Merge branch 'master' into infix_to_prefix_new_algo
Hardvan bcbabb9
Update directory
Hardvan d7031aa
Fix comment
Hardvan File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
package com.thealgorithms.stacks; | ||
|
||
import java.util.Stack; | ||
import java.util.regex.Matcher; | ||
import java.util.regex.Pattern; | ||
|
||
public final class InfixToPrefix { | ||
private InfixToPrefix() { | ||
} | ||
|
||
/** | ||
* Convert an infix expression to a prefix expression using stack. | ||
* | ||
* @param infixExpression the infix expression to convert | ||
* @return the prefix expression | ||
* @throws IllegalArgumentException if the infix expression has unbalanced brackets | ||
* @throws NullPointerException if the infix expression is null | ||
*/ | ||
public static String infix2Prefix(String infixExpression) throws IllegalArgumentException { | ||
if (infixExpression == null) { | ||
throw new NullPointerException("Input expression cannot be null."); | ||
} | ||
infixExpression = infixExpression.trim(); | ||
if (infixExpression.isEmpty()) { | ||
return ""; | ||
} | ||
if (!BalancedBrackets.isBalanced(filterBrackets(infixExpression))) { | ||
throw new IllegalArgumentException("Invalid expression: unbalanced brackets."); | ||
} | ||
|
||
StringBuilder output = new StringBuilder(); | ||
Stack<Character> stack = new Stack<>(); | ||
// Reverse the infix expression for prefix conversion | ||
String reversedInfix = new StringBuilder(infixExpression).reverse().toString(); | ||
for (char element : reversedInfix.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.pop(); | ||
} else { | ||
while (!stack.isEmpty() && precedence(element) < precedence(stack.peek())) { | ||
output.append(stack.pop()); | ||
} | ||
stack.push(element); | ||
} | ||
} | ||
while (!stack.isEmpty()) { | ||
output.append(stack.pop()); | ||
} | ||
|
||
// Reverse the result to get the prefix expression | ||
return output.reverse().toString(); | ||
} | ||
|
||
/** | ||
* Determines the precedence of an operator. | ||
* | ||
* @param operator the operator whose precedence is to be determined | ||
* @return the precedence of the operator | ||
*/ | ||
private static int precedence(char operator) { | ||
switch (operator) { | ||
case '+': | ||
case '-': | ||
return 0; | ||
case '*': | ||
case '/': | ||
return 1; | ||
case '^': | ||
return 2; | ||
default: | ||
return -1; | ||
} | ||
} | ||
|
||
/** | ||
* Filters out all characters from the input string except brackets. | ||
* | ||
* @param input the input string to filter | ||
* @return a string containing only brackets from the input string | ||
*/ | ||
private static String filterBrackets(String input) { | ||
Pattern pattern = Pattern.compile("[^(){}\\[\\]<>]"); | ||
Matcher matcher = pattern.matcher(input); | ||
return matcher.replaceAll(""); | ||
} | ||
} |
44 changes: 44 additions & 0 deletions
44
src/test/java/com/thealgorithms/stacks/InfixToPrefixTest.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package com.thealgorithms.stacks; | ||
|
||
import static org.junit.jupiter.api.Assertions.assertEquals; | ||
import static org.junit.jupiter.api.Assertions.assertThrows; | ||
|
||
import java.util.stream.Stream; | ||
import org.junit.jupiter.api.Test; | ||
import org.junit.jupiter.params.ParameterizedTest; | ||
import org.junit.jupiter.params.provider.Arguments; | ||
import org.junit.jupiter.params.provider.MethodSource; | ||
|
||
public class InfixToPrefixTest { | ||
|
||
@ParameterizedTest | ||
@MethodSource("provideValidExpressions") | ||
void testValidExpressions(String infix, String expectedPrefix) throws Exception { | ||
assertEquals(expectedPrefix, InfixToPrefix.infix2Prefix(infix)); | ||
} | ||
|
||
@Test | ||
void testEmptyString() { | ||
// Assuming that an empty string returns an empty prefix or throws an exception | ||
assertEquals("", InfixToPrefix.infix2Prefix("")); | ||
} | ||
|
||
@Test | ||
void testNullValue() { | ||
// Assuming that a null input throws a NullPointerException | ||
assertThrows(NullPointerException.class, () -> InfixToPrefix.infix2Prefix(null)); | ||
} | ||
|
||
private static Stream<Arguments> provideValidExpressions() { | ||
return Stream.of(Arguments.of("3+2", "+32"), // Simple addition | ||
Hardvan marked this conversation as resolved.
Show resolved
Hide resolved
|
||
Arguments.of("1+(2+3)", "+1+23"), // Parentheses | ||
Arguments.of("(3+4)*5-6", "-*+3456"), // Nested operations | ||
Arguments.of("a+b*c", "+a*bc"), // Multiplication precedence | ||
Arguments.of("a+b*c/d", "+a/*bcd"), // Division precedence | ||
Arguments.of("a+b*c-d", "-+a*bcd"), // Subtraction precedence | ||
Arguments.of("a+b*c/d-e", "-+a/*bcde"), // Mixed precedence | ||
Arguments.of("a+b*(c-d)", "+a*b-cd"), // Parentheses precedence | ||
Arguments.of("a+b*(c-d)/e", "+a/*b-cde") // Mixed precedence with parentheses | ||
); | ||
} | ||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.