This EmptyStackException continues to pop up. Obliviously there is nothing in my stack, but the first element that the User inputs. However, I am not sure where the code is flawed. (many spots) but I just need to fix this error.
import java.util.*;
public class stacks2 {
public static void main (String []args){
System.out.printf("Enter a math equation in reverse polish notation:\n");
//Create stack of Strings
Stack<String> rpnStack = new Stack<String>();
//Create Scanner
Scanner input = new Scanner(System.in);
//String in = input.next();
while(input != null) {
String in = input.next();
// Tokenize string based on spaces.
StringTokenizer st = new StringTokenizer(in, " ", true);
while (st.hasMoreTokens()) {
rpnStack.push(st.nextToken());
}
//Send stack to Calculation Method
calculate(rpnStack);
}
}
public static void calculate(Stack<String> stack) {
// Base case: stack is empty => Error, or finished
if (!stack.isEmpty())
// throw new StackUnderflowException("Empty Stack");
// Base case: stack has 1 element, which is the answer => finished
if (stack.size() == 1)
System.out.printf("Finished, Answer: %s\n",stack.peek());
// Recursive case: stack more elements on it.
if (stack.size() > 1){
String temp1 = stack.peek();
stack.pop();
String temp2 = stack.peek();
stack.pop();
String temp3 = stack.peek();
stack.pop();
if (temp3.equals("+")){
float resultant = Float.parseFloat(temp1) + Float.parseFloat(temp2);
stack.push(String.valueOf(resultant));
//System.out.println(resultant);
calculate(stack);
}
if (temp3.equals("-")){
float resultant = Float.parseFloat(temp1) - Float.parseFloat(temp2);
stack.push(String.valueOf(resultant));
//System.out.println(resultant);
calculate(stack);
}
else if (temp3.equals("*")){
float resultant = Float.parseFloat(temp1) * Float.parseFloat(temp2);
stack.push(String.valueOf(resultant));
//System.out.println(resultant);
calculate(stack);
}
else if (temp3.equals("/")){
float resultant = Float.parseFloat(temp1) / Float.parseFloat(temp2);
stack.push(String.valueOf(resultant));
//System.out.println(resultant);
calculate(stack);
}
else{
System.out.printf("Something severely has gone wrong.");
}
}
}
}
the input and error:
:~ Home$ java stacks2
Enter a math equation in reverse polish notation:
4 5 * 6 -
Finished, Answer: 4
Exception in thread "main" java.util.EmptyStackException
at java.util.Stack.peek(Stack.java:85)
at stacks2.calculate(stacks2.java:41)
at stacks2.main(stacks2.java:22)
clearly this is only taking the first element which makes me think my while loop at 17 is the cause. Any insight?
String in = input.next();
reads you one word, then you are trying to tokenise that word. Perhaps you meantString in = input.nextLine();
http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Scanner.html#next() http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Scanner.html#nextLine()
Also, you have these two lines in your code.
This is plain wrong. Without its curly braces, the
if
affects the next statement. It is not the comment - it is the following if.This:
is equivalent to this:
and this:
Moral: always use curly brackets with an
if
AND don't comment out assertions. Even if you do comment out assertions, comment them completely, and not one half of them, epecially when the other half is an un-bracketed if.Third, your logic is flawed. You do this:
push all symbols to the stack, then pop the top three and consider them an operator and two numbers. This will work with some inputs if you use a queue instead.
By your logic, this will pop
* 6 -
and crash. If you use a queue, it will work in this caseBut not is this case:
Next, you pop 2 1 1 and crash.
Instead, what you should do:
A stack is LIFO, or "Last in, First out". So when you have an input sequence of
4 5 * 6 -
and do this:The first thing you pop will be "-", the second thing will be "6", and the third thing will be "*". Is this what you expect?
Also, instead of:
You can do: