From 20892f7811d5c88cc060a6a0a73e92726bae302b Mon Sep 17 00:00:00 2001 From: Hardik Pawar Date: Thu, 3 Oct 2024 19:51:34 +0530 Subject: [PATCH 1/6] Add `PrefixToInfix.java` new algorithm --- .../thealgorithms/stacks/PrefixToInfix.java | 71 +++++++++++++++++++ .../stacks/PrefixToInfixTest.java | 40 +++++++++++ 2 files changed, 111 insertions(+) create mode 100644 src/main/java/com/thealgorithms/stacks/PrefixToInfix.java create mode 100644 src/test/java/com/thealgorithms/stacks/PrefixToInfixTest.java diff --git a/src/main/java/com/thealgorithms/stacks/PrefixToInfix.java b/src/main/java/com/thealgorithms/stacks/PrefixToInfix.java new file mode 100644 index 000000000000..bf3a1768c38f --- /dev/null +++ b/src/main/java/com/thealgorithms/stacks/PrefixToInfix.java @@ -0,0 +1,71 @@ +package com.thealgorithms.stacks; + +import java.util.Stack; + +/** + * Prefix to Infix implementation via Stack + * + * Function: String getPrefixToInfix(String prefix) + * Returns the Infix Expression for the given prefix parameter. + * + * Avoid using parentheses/brackets/braces for the prefix string. + * Prefix Expressions don't require these. + * + * @author OpenAI + * + */ + +public final class PrefixToInfix { + private PrefixToInfix() { + } + + /** + * Determines if a given character is a valid arithmetic operator. + * + * @param token the character to check + * @return true if the character is an operator, false otherwise + */ + public static boolean isOperator(char token) { + return token == '+' || token == '-' || token == '/' || token == '*' || token == '^'; + } + + /** + * Converts a valid prefix expression to an infix expression. + * + * @param prefix the prefix expression to convert + * @return the equivalent infix expression + * @throws NullPointerException if the prefix expression is null + */ + public static String getPrefixToInfix(String prefix) { + if (prefix == null) { + throw new NullPointerException("Null prefix expression"); + } + if (prefix.isEmpty()) { + return ""; + } + + Stack stack = new Stack<>(); + + // Iterate over the prefix expression from right to left + for (int i = prefix.length() - 1; i >= 0; i--) { + char token = prefix.charAt(i); + + if (isOperator(token)) { + // Pop two operands from stack + String operandA = stack.pop(); + String operandB = stack.pop(); + + // Form the infix expression with parentheses + String infix = "(" + operandA + token + operandB + ")"; + + // Push the resulting infix expression back onto the stack + stack.push(infix); + } else { + // Push operand onto stack + stack.push(Character.toString(token)); + } + } + + return stack.pop(); // final element on the stack is the full infix expression + } +} diff --git a/src/test/java/com/thealgorithms/stacks/PrefixToInfixTest.java b/src/test/java/com/thealgorithms/stacks/PrefixToInfixTest.java new file mode 100644 index 000000000000..745f81514df1 --- /dev/null +++ b/src/test/java/com/thealgorithms/stacks/PrefixToInfixTest.java @@ -0,0 +1,40 @@ +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; + +class PrefixToInfixTest { + + @ParameterizedTest + @MethodSource("provideValidPrefixToInfixTestCases") + void testValidPrefixToInfixConversion(String prefix, String expectedInfix) { + assertEquals(expectedInfix, PrefixToInfix.getPrefixToInfix(prefix)); + } + + static Stream provideValidPrefixToInfixTestCases() { + return Stream.of( + Arguments.of("A", "A"), // Single operand + Arguments.of("+AB", "(A+B)"), // Addition + Arguments.of("*+ABC", "((A+B)*C)"), // Addition and multiplication + Arguments.of("-+A*BCD", "((A+(B*C))-D)"), // Mixed operators + Arguments.of("/-A*BC+DE", "((A-(B*C))/(D+E))"), // Mixed operators + Arguments.of("^+AB*CD", "((A+B)^(C*D))") // Mixed operators + ); + } + + @Test + void testEmptyPrefixExpression() { + assertEquals("", PrefixToInfix.getPrefixToInfix("")); + } + + @Test + void testNullPrefixExpression() { + assertThrows(NullPointerException.class, () -> PrefixToInfix.getPrefixToInfix(null)); + } +} From 840081adeec9ba30d0e2794894cdfcb42f81880a Mon Sep 17 00:00:00 2001 From: Hardvan Date: Thu, 3 Oct 2024 14:21:53 +0000 Subject: [PATCH 2/6] Update directory --- DIRECTORY.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/DIRECTORY.md b/DIRECTORY.md index ee09790ed64d..720079f4e7ad 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -545,6 +545,7 @@ * [NextGreaterElement](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/NextGreaterElement.java) * [NextSmallerElement](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/NextSmallerElement.java) * [PostfixToInfix](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/PostfixToInfix.java) + * [PrefixToInfix](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/PrefixToInfix.java) * [StackPostfixNotation](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/StackPostfixNotation.java) * strings * [AhoCorasick](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/AhoCorasick.java) @@ -967,6 +968,7 @@ * [NextGreaterElementTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/stacks/NextGreaterElementTest.java) * [NextSmallerElementTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/stacks/NextSmallerElementTest.java) * [PostfixToInfixTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/stacks/PostfixToInfixTest.java) + * [PrefixToInfixTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/stacks/PrefixToInfixTest.java) * [StackPostfixNotationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/stacks/StackPostfixNotationTest.java) * strings * [AhoCorasickTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/AhoCorasickTest.java) From ff1ad5900231546aa3b46a672074c39ae3bb0e2d Mon Sep 17 00:00:00 2001 From: Hardik Pawar Date: Thu, 3 Oct 2024 19:53:09 +0530 Subject: [PATCH 3/6] Fix clang error --- src/test/java/com/thealgorithms/stacks/PrefixToInfixTest.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/test/java/com/thealgorithms/stacks/PrefixToInfixTest.java b/src/test/java/com/thealgorithms/stacks/PrefixToInfixTest.java index 745f81514df1..92cc0263c18e 100644 --- a/src/test/java/com/thealgorithms/stacks/PrefixToInfixTest.java +++ b/src/test/java/com/thealgorithms/stacks/PrefixToInfixTest.java @@ -18,8 +18,7 @@ void testValidPrefixToInfixConversion(String prefix, String expectedInfix) { } static Stream provideValidPrefixToInfixTestCases() { - return Stream.of( - Arguments.of("A", "A"), // Single operand + return Stream.of(Arguments.of("A", "A"), // Single operand Arguments.of("+AB", "(A+B)"), // Addition Arguments.of("*+ABC", "((A+B)*C)"), // Addition and multiplication Arguments.of("-+A*BCD", "((A+(B*C))-D)"), // Mixed operators From f01e868ecf9aa5cc6c20395c6a645737ae3e6b2c Mon Sep 17 00:00:00 2001 From: Hardvan Date: Thu, 3 Oct 2024 14:26:31 +0000 Subject: [PATCH 4/6] Update directory --- DIRECTORY.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/DIRECTORY.md b/DIRECTORY.md index e3564677e399..3f28777b2781 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -238,6 +238,7 @@ * [KnapsackMemoization](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/KnapsackMemoization.java) * [LevenshteinDistance](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/LevenshteinDistance.java) * [LongestAlternatingSubsequence](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/LongestAlternatingSubsequence.java) + * [LongestArithmeticSubsequence](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/LongestArithmeticSubsequence.java) * [LongestCommonSubsequence](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/LongestCommonSubsequence.java) * [LongestIncreasingSubsequence](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/LongestIncreasingSubsequence.java) * [LongestPalindromicSubsequence](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/LongestPalindromicSubsequence.java) @@ -734,6 +735,7 @@ * [KnapsackTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/KnapsackTest.java) * [LevenshteinDistanceTests](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/LevenshteinDistanceTests.java) * [LongestAlternatingSubsequenceTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/LongestAlternatingSubsequenceTest.java) + * [LongestArithmeticSubsequenceTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/LongestArithmeticSubsequenceTest.java) * [LongestIncreasingSubsequenceTests](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/LongestIncreasingSubsequenceTests.java) * [LongestPalindromicSubstringTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/LongestPalindromicSubstringTest.java) * [LongestValidParenthesesTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/LongestValidParenthesesTest.java) From ba07fdbe173ebf83526b2898e705453a4e5daf69 Mon Sep 17 00:00:00 2001 From: Hardik Pawar Date: Thu, 3 Oct 2024 19:59:32 +0530 Subject: [PATCH 5/6] Fix comment --- src/main/java/com/thealgorithms/stacks/PrefixToInfix.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main/java/com/thealgorithms/stacks/PrefixToInfix.java b/src/main/java/com/thealgorithms/stacks/PrefixToInfix.java index bf3a1768c38f..55b70123af02 100644 --- a/src/main/java/com/thealgorithms/stacks/PrefixToInfix.java +++ b/src/main/java/com/thealgorithms/stacks/PrefixToInfix.java @@ -10,9 +10,6 @@ * * Avoid using parentheses/brackets/braces for the prefix string. * Prefix Expressions don't require these. - * - * @author OpenAI - * */ public final class PrefixToInfix { From 4de9a2255ab922b5eada470c89250dc73ee285ae Mon Sep 17 00:00:00 2001 From: Hardik Pawar Date: Fri, 4 Oct 2024 20:22:57 +0530 Subject: [PATCH 6/6] Add suggested changes --- .../com/thealgorithms/stacks/PrefixToInfix.java | 15 ++++++++------- .../thealgorithms/stacks/PrefixToInfixTest.java | 5 +++++ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/thealgorithms/stacks/PrefixToInfix.java b/src/main/java/com/thealgorithms/stacks/PrefixToInfix.java index 55b70123af02..41eb974b0e5b 100644 --- a/src/main/java/com/thealgorithms/stacks/PrefixToInfix.java +++ b/src/main/java/com/thealgorithms/stacks/PrefixToInfix.java @@ -3,15 +3,12 @@ import java.util.Stack; /** - * Prefix to Infix implementation via Stack + * Converts a prefix expression to an infix expression using a stack. * - * Function: String getPrefixToInfix(String prefix) - * Returns the Infix Expression for the given prefix parameter. - * - * Avoid using parentheses/brackets/braces for the prefix string. - * Prefix Expressions don't require these. + * The input prefix expression should consist of + * valid operands (letters or digits) and operators (+, -, *, /, ^). + * Parentheses are not required in the prefix string. */ - public final class PrefixToInfix { private PrefixToInfix() { } @@ -63,6 +60,10 @@ public static String getPrefixToInfix(String prefix) { } } + if (stack.size() != 1) { + throw new ArithmeticException("Malformed prefix expression"); + } + return stack.pop(); // final element on the stack is the full infix expression } } diff --git a/src/test/java/com/thealgorithms/stacks/PrefixToInfixTest.java b/src/test/java/com/thealgorithms/stacks/PrefixToInfixTest.java index 92cc0263c18e..83fd09e1bbf6 100644 --- a/src/test/java/com/thealgorithms/stacks/PrefixToInfixTest.java +++ b/src/test/java/com/thealgorithms/stacks/PrefixToInfixTest.java @@ -36,4 +36,9 @@ void testEmptyPrefixExpression() { void testNullPrefixExpression() { assertThrows(NullPointerException.class, () -> PrefixToInfix.getPrefixToInfix(null)); } + + @Test + void testMalformedPrefixExpression() { + assertThrows(ArithmeticException.class, () -> PrefixToInfix.getPrefixToInfix("+ABC")); + } }