feat: Add PrefixEvaluator new algorithm with Junit tests (#5755)

This commit is contained in:
Hardik Pawar
2024-10-13 16:27:05 +05:30
committed by GitHub
parent b0c8a8f0ce
commit bae7f89156
3 changed files with 105 additions and 0 deletions

View File

@ -600,6 +600,7 @@
* [NextSmallerElement](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/NextSmallerElement.java)
* [PostfixEvaluator](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/PostfixEvaluator.java)
* [PostfixToInfix](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/PostfixToInfix.java)
* [PrefixEvaluator](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/PrefixEvaluator.java)
* [PrefixToInfix](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/PrefixToInfix.java)
* [SortStack](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/SortStack.java)
* [StackPostfixNotation](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/StackPostfixNotation.java)
@ -1131,6 +1132,7 @@
* [NextSmallerElementTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/stacks/NextSmallerElementTest.java)
* [PostfixEvaluatorTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/stacks/PostfixEvaluatorTest.java)
* [PostfixToInfixTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/stacks/PostfixToInfixTest.java)
* [PrefixEvaluatorTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/stacks/PrefixEvaluatorTest.java)
* [PrefixToInfixTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/stacks/PrefixToInfixTest.java)
* [SortStackTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/stacks/SortStackTest.java)
* [StackPostfixNotationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/stacks/StackPostfixNotationTest.java)

View File

@ -0,0 +1,76 @@
package com.thealgorithms.stacks;
import java.util.Set;
import java.util.Stack;
/**
* Evaluate a prefix (Polish) expression using a stack.
*
* <p>Example: Expression "+ * 2 3 4" results in 10.
* <p>Applications: Useful for implementing compilers and interpreters.
*
* @author Hardvan
*/
public final class PrefixEvaluator {
private PrefixEvaluator() {
}
private static final Set<String> OPERATORS = Set.of("+", "-", "*", "/");
/**
* Evaluates the given prefix expression and returns the result.
*
* @param expression The prefix expression as a string with operands and operators separated by spaces.
* @return The result of evaluating the prefix expression.
* @throws IllegalArgumentException if the expression is invalid.
*/
public static int evaluatePrefix(String expression) {
Stack<Integer> stack = new Stack<>();
String[] tokens = expression.split("\\s+");
for (int i = tokens.length - 1; i >= 0; i--) {
String token = tokens[i];
if (isOperator(token)) {
int operand1 = stack.pop();
int operand2 = stack.pop();
stack.push(applyOperator(token, operand1, operand2));
} else {
stack.push(Integer.valueOf(token));
}
}
if (stack.size() != 1) {
throw new IllegalArgumentException("Invalid expression");
}
return stack.pop();
}
/**
* Checks if the given token is an operator.
*
* @param token The token to check.
* @return true if the token is an operator, false otherwise.
*/
private static boolean isOperator(String token) {
return OPERATORS.contains(token);
}
/**
* Applies the given operator to the two operands.
*
* @param operator The operator to apply.
* @param a The first operand.
* @param b The second operand.
* @return The result of applying the operator to the operands.
*/
private static int applyOperator(String operator, int a, int b) {
return switch (operator) {
case "+" -> a + b;
case "-" -> a - b;
case "*" -> a * b;
case "/" -> a / b;
default -> throw new IllegalArgumentException("Invalid operator");
};
}
}

View File

@ -0,0 +1,27 @@
package com.thealgorithms.stacks;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import java.util.EmptyStackException;
import org.junit.jupiter.api.Test;
public class PrefixEvaluatorTest {
@Test
public void testValidExpressions() {
assertEquals(10, PrefixEvaluator.evaluatePrefix("+ * 2 3 4"));
assertEquals(5, PrefixEvaluator.evaluatePrefix("- + 7 3 5"));
assertEquals(6, PrefixEvaluator.evaluatePrefix("/ * 3 2 1"));
}
@Test
public void testInvalidExpression() {
assertThrows(EmptyStackException.class, () -> PrefixEvaluator.evaluatePrefix("+ 3"));
}
@Test
public void testMoreThanOneStackSizeAfterEvaluation() {
assertThrows(IllegalArgumentException.class, () -> PrefixEvaluator.evaluatePrefix("+ 3 4 5"));
}
}