空堆栈异常堆栈、异常

2023-09-08 08:45:58 作者:弑

此 EmptyStackException 继续弹出.不知不觉中,我的堆栈中没有任何内容,而是用户输入的第一个元素.但是,我不确定代码的缺陷在哪里.(很多地方)但我只需要修复这个错误.

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:
");

//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
",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.");
            }
        }  
    }
}

输入和错误:

:~ 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)

显然,这只是采用第一个元素,这让我认为我在 17 处的 while 循环是原因.有什么见解吗?

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(); 读取你一个单词,然后你试图标记那个单词.也许你的意思是 String in = input.nextLine();

String in = input.next(); reads you one word, then you are trying to tokenise that word. Perhaps you meant String 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.

if (!stack.isEmpty())
  // throw new StackUnderflowException("Empty Stack");

这是完全错误的.如果没有大括号,if 会影响下一条语句.这不是评论 - 它是以下 if.

This is plain wrong. Without its curly braces, the if affects the next statement. It is not the comment - it is the following if.

这个:

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
",stack.peek());

等价于:

if (!stack.isEmpty())
    if (stack.size() == 1)
        System.out.printf("Finished, Answer: %s
",stack.peek());

还有这个:

if (!stack.isEmpty() && stack.size() == 1){
    System.out.printf("Finished, Answer: %s
",stack.peek());
}

道德:始终使用带有 if 的大括号,并且不要注释掉断言.即使您确实注释掉了断言,也要完整地注释它们,而不是其中的一半,尤其是当另一半是未加括号的 if 时.

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.

4 5 * 6 -

按照您的逻辑,这将弹出 * 6 - 并崩溃.如果您使用队列,它会工作在这种情况下

By your logic, this will pop * 6 - and crash. If you use a queue, it will work in this case

4 5 * 6 - 
20 6 -
14

但不是这种情况:

(1+1)*(1+1)
express as RPN
1 1 + 1 1 + *
2 1 1 + *

接下来,你弹出 2 1 1 并崩溃.

Next, you pop 2 1 1 and crash.

相反,你应该怎么做:

Read the input. For each symbol:
  if it is a number,
    push it on the stack.
  else,
    pop two numbers from the stack,
    perform the operation and
     push the result.