Implement ReversePolishStack.evaluate() on current stack with push-back.

Co-Authored-By: td1223
This commit is contained in:
Gleb Koval 2024-11-05 17:05:23 +00:00
parent 1e84974198
commit b9dbfb86ad
Signed by: cyclane
GPG Key ID: 15E168A8B332382C
2 changed files with 56 additions and 0 deletions

View File

@ -12,4 +12,29 @@ public class ReversePolishStack {
public void push(IntOperator intOperator) { public void push(IntOperator intOperator) {
stack.push(intOperator); stack.push(intOperator);
} }
private int evaluateNext() {
if (stack.isEmpty()) {
throw new ArithmeticException("No operators to evaluate");
}
IntOperator intOperator = stack.pop();
Stack<Integer> args = new Stack<>();
while (args.size() < intOperator.getOperands()) {
if (stack.isEmpty()) {
throw new ArithmeticException("Not enough arguments to evaluate operator");
}
args.push(evaluateNext());
}
return intOperator.evaluate(args);
}
public int evaluate() {
int result = evaluateNext();
if (!stack.isEmpty()) {
throw new ArithmeticException("Invalid notation, too many operators");
}
stack.push(new IntOperator(0, args -> result));
return result;
}
} }

View File

@ -4,6 +4,7 @@ import org.junit.Test;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.is;
import static org.junit.Assert.fail;
public class ReversePolishStackTest { public class ReversePolishStackTest {
final ReversePolishStack reversePolishStack = new ReversePolishStack(); final ReversePolishStack reversePolishStack = new ReversePolishStack();
@ -20,4 +21,34 @@ public class ReversePolishStackTest {
reversePolishStack.push(new IntOperator(0, args -> 2)); reversePolishStack.push(new IntOperator(0, args -> 2));
assertThat(reversePolishStack.getSize(), is(2)); assertThat(reversePolishStack.getSize(), is(2));
} }
@Test
public void canEvaluateReversePolishStack() {
reversePolishStack.push(new IntOperator(0, args -> 10));
reversePolishStack.push(new IntOperator(0, args -> 25));
reversePolishStack.push(new IntOperator(2, args -> args.get(0) + args.get(1)));
assertThat(reversePolishStack.evaluate(), is(35));
}
@Test
public void evaluatePushesBack() {
reversePolishStack.push(new IntOperator(0, args -> 10));
reversePolishStack.push(new IntOperator(0, args -> 25));
reversePolishStack.push(new IntOperator(2, args -> args.get(0) + args.get(1)));
reversePolishStack.evaluate();
assertThat(reversePolishStack.getSize(), is(1));
assertThat(reversePolishStack.evaluate(), is(35));
}
@Test
public void evaluateThrowsOnInvalidNotation() {
reversePolishStack.push(new IntOperator(0, args -> 10));
reversePolishStack.push(new IntOperator(0, args -> 25));
try {
reversePolishStack.evaluate();
fail("Expected ArithmeticException to be thrown when too many operators");
} catch (ArithmeticException e) {
// good
}
}
} }