中缀表达式求解器中的空堆栈异常

Posted

技术标签:

【中文标题】中缀表达式求解器中的空堆栈异常【英文标题】:Empty Stack Exception in Infix Expression Solver 【发布时间】:2018-04-18 05:29:26 【问题描述】:

所以我的程序假设采用语法正确的中缀表达式 包含来自 GUI 的整数操作数和四个算术运算符 (+ - * /) 并显示结果。不幸的是,如果我输入一个像 3 + 4 这样的简单表达式,程序会抛出一个空堆栈异常。我才刚刚开始使用堆栈,所以如果我弄错了一些简单的东西,请原谅我。请帮忙!

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;


public class inFix extends JFrame

   private Container contents;
   private JLabel infixLabel, resultLabel, result;
   private JTextField infixText;
   private JButton evaluate;

   public inFix()
   
      super("Infix Expresion Evaluator");
      contents = getContentPane();
      contents.setLayout( new FlowLayout() );

      infixLabel = new JLabel("Enter Infix Expression:");
      infixText = new JTextField("", 14);

      evaluate = new JButton("Evaluate");

      resultLabel = new JLabel("Result:");
      result = new JLabel("???");

      contents.add( infixLabel );
      contents.add( infixText );
      contents.add( evaluate );
      contents.add( resultLabel );
      contents.add( result );


      ButtonHandler bh = new ButtonHandler();

      evaluate.addActionListener( bh );

      setSize( 350, 200 );
      setVisible( true );
   

   private class ButtonHandler implements ActionListener
   
      public void actionPerformed( ActionEvent ae )
      
         result.setText(infix(infixText.getText()));
      
   


   public String infix(String expression)
   
      expression=expression.replaceAll("[\t\n ]", "")+"=";
      String operator = "*/+-";
      int value1, value2;
      char ch;
      StringTokenizer tokenizer = new StringTokenizer(expression, operator, true); 
      Stack<Integer> valueStack = new Stack<Integer>();
      Stack<Character> operatorStack = new Stack<Character>();

      while(tokenizer.hasMoreTokens())
      
         String token = tokenizer.nextToken();
         if(isInteger(token) == true)
            valueStack.push(Integer.parseInt(token));
         else if(token.charAt(0) == '(')
            operatorStack.push(token.charAt(0));
         else if(token.charAt(0) == ')')
            while(operatorStack.peek() != '(')
            
               value1 = valueStack.pop();
               value2 = valueStack.pop();
               valueStack.push(solver(value1, value2, operatorStack.pop()));
            
         else if(token.charAt(0) == '+' || token.charAt(0) == '-' || token.charAt(0) == '*' || token.charAt(0) == '/')
         
            while(!operatorStack.isEmpty() && precedence(token.charAt(0)) <= precedence(operatorStack.peek()))
            
               value1 = valueStack.pop();
               value2 = valueStack.pop();
               valueStack.push(solver(value1, value2, token.charAt(0)));
            
            operatorStack.push(token.charAt(0));
         
      
      while(!operatorStack.isEmpty())
      
         value1 = valueStack.pop();
         value2 = valueStack.pop();
         ch = operatorStack.pop();
         valueStack.push(solver(value1, value2, ch));
      


      String result = Integer.toString(valueStack.pop());
      return result;     
   

   public static boolean isInteger(String s)
   
      try
       
         Integer.parseInt(s);
       
      catch(NumberFormatException e)
      
         return false; 
       
      catch(NullPointerException e) 
      
         return false;
      
      return true;
   
   public int solver( int value1, int value2, char operator)
   
      if(operator == '*')
         return value1 * value2;
      else if(operator == '/')
         return value1 / value2;
      else if(operator == '+')
         return value1 + value2;
      else if(operator == '-')
         return value1 - value2;
      else
         return 0;
   

   public int precedence(char op)
   
      if(op == '+' || op == '-')
         return 1;
      else if(op == '*' || op == '/')
         return 2;
      else
         return -1;
      


   public static void main( String [] args )
   
      inFix infixsolver = new inFix();
      infixsolver.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
   


【问题讨论】:

【参考方案1】:

假设输入表达式为“3+4” 第 54 行

expression=expression.replaceAll("[\t\n ]", "")+"=";

表达式变成“3+4=” 在标记器操作之后,标记为 ["3","+","4="],这会在第 65 行为标记 "4=" 生成错误结果

if(isInteger(token) == true)

因此在第 89 行弹出时 value 的数量不够

     value2 = valueStack.pop();

要解决问题,请删除第 54 行中的 +"="

expression=expression.replaceAll("[\t\n ]", "")+"=";

【讨论】:

以上是关于中缀表达式求解器中的空堆栈异常的主要内容,如果未能解决你的问题,请参考以下文章

堆栈入门-简单计算器模板-中缀转后缀

中缀表达式转换成后缀表达式并求值

使用堆栈将中缀表达式转换为前缀时,如果扫描和堆栈顶部的运算符具有相同的优先级,应该怎么做?

后缀表达式转为中缀表达式

数据结构(C语言版)严蔚敏->用栈求解表达式(中缀表达式后缀表达式)

数据结构(C语言版)严蔚敏->用栈求解表达式(中缀表达式后缀表达式)