Java 数据结构和算法 计算表达式问题

本文讲述了使用Java结合栈和队列解决计算表达式的问题,包括将中缀表达式转为后缀表达式,以及计算后缀表达式的值。通过实例展示了转换规则及代码实现。
摘要由CSDN通过智能技术生成

上一节介绍了栈和队列两种数据结构,这里接介绍一个栈和队列的综合应用:计算表达式

计算表达式

以前做小练习的时候也做过小的计算器,对表达式的计算是很重要也是很头疼的一部分,这里就来看看如何使用栈和队列来实现。
计算表达式分两步:

  • 将算术表达式转换为后缀表达式。
  • 计算后缀表达式的值。
中缀表达式后缀表达式
A+B-CAB+C-
A*B/CAB*C/
A+B*CABC*+
A*(B+C)ABC+*
A*B+C*DAB*CD*+
A+B*(C-D/(E+F))ABCDEF+/-*+

举例一个计算过程:

这里写图片描述

中缀表达式转换为后缀表达式的转换规则:

中缀表达式读取的字符动作
操作数写至输出
左括号压入栈
右括号栈非空时重复一下步骤:弹出一项,若项不为(,则写至输出,若为(退出循环

代码实现:


import java.io.*;          

class StackX
   {
   private int maxSize;
   private char[] stackArray;
   private int top;

   public StackX(int s)       // constructor
      {
      maxSize = s;
      stackArray = new char[maxSize];
      top = -1;
      }

   public void push(char j)  // 压入数据项至栈顶
      { stackArray[++top] = j; }

   public char pop()         // 从栈顶拿走一项元素  (栈大小改变)
      { return stackArray[top--]; }
//--------------------------------------------------------------
   public char peek()        // 获取栈顶元素  (只获得栈顶元素  栈不变)
      { return stackArray[top]; }
//--------------------------------------------------------------
   public boolean isEmpty()  // 判断是否为空
      { return (top == -1); }
//-------------------------------------------------------------
   public int size()         // 获取栈大小
      { return top+1; }
//--------------------------------------------------------------
   public char peekN(int n)  // 获取指定元素
      { return stackArray[n]; }
//--------------------------------------------------------------
   public void displayStack(String s)
      {
      System.out.print(s);
      System.out.print("Stack (bottom-->top): ");
      for(int j=0; j<size(); j++)
         {
         System.out.print( peekN(j) );
         System.out.print(' ');
         }
      System.out.println("");
      }
//--------------------------------------------------------------
   }  
class InToPost                  
   {
   private StackX theStack;
   private String input;
   private String output = "";

   public InToPost(String in)   
      {
      input = in;
      int stackSize = input.length();
      theStack = new StackX(stackSize);
      }

   public String doTrans()      
      {
      for(int j=0; j<input.length(); j++)      // 遍历
         {
         char ch = input.charAt(j);            
         theStack.displayStack("For "+ch+" "); 
         switch(ch)
            {
            case '+':               // + 或 -
            case '-':
               gotOper(ch, 1);    
               break;               
            case '*':               // * 或  /
            case '/':
               gotOper(ch, 2);     
               break;               
            case '(':               
               theStack.push(ch);   
               break;
            case ')':               
               gotParen(ch);        
               break;
            default:                
               output = output + ch; 
               break;
            }  
         }  
      while( !theStack.isEmpty() )     
         {
         theStack.displayStack("While ");  
         output = output + theStack.pop(); 
         }
      theStack.displayStack("End   ");     
      return output;                   
      }  

   public  void gotOper(char opThis, int prec1)
      {                                
      while( !theStack.isEmpty() )
         {
         char opTop = theStack.pop();
         if( opTop == '(' )            
            {
            theStack.push(opTop);      
            break;
            }
         else                         
            {
            int prec2;                 

            if(opTop=='+' || opTop=='-')  
               prec2 = 1;
            else
               prec2 = 2;
            if(prec2 < prec1)          
               {                       
               theStack.push(opTop);   
               break;
               }
            else                       
               output = output + opTop;  
            }  
         }  
      theStack.push(opThis);           
      }  

   public  void gotParen(char ch)
      {                             
      while( !theStack.isEmpty() )
         {
         char chx = theStack.pop();
         if( chx == '(' )           
            break;                 
         else                      
            output = output + chx;  
         }  
      }  
//--------------------------------------------------------------
   }  



class InfixApp
   {
   public static void main(String[] args) throws IOException
      {
      String input, output;
      while(true)
         {
         System.out.print("Enter infix: ");
         System.out.flush();
         input = getString();         
         if( input.equals("") )       
            break;

         InToPost theTrans = new InToPost(input);
         output = theTrans.doTrans(); // do the translation
         System.out.println("Postfix is " + output + '\n');
         } 
      }  
//--------------------------------------------------------------
   public static String getString() throws IOException
      {
      InputStreamReader isr = new InputStreamReader(System.in);
      BufferedReader br = new BufferedReader(isr);
      String s = br.readLine();
      return s;
      }
//--------------------------------------------------------------
   } 

输出效果:

这里写图片描述

接下来就是如何从后缀表达式求值:

后缀表达式读取的字符动作
操作数入栈
操作符从栈中提取两个操作数,计算结果,结果入栈

代码实现:

import java.io.*;           

class StackX
   {
   private int maxSize;
   private int[] stackArray;
   private int top;

   public StackX(int size)      // constructor
      {
      maxSize = size;
      stackArray = new int[maxSize];
      top = -1;
      }

   public void push(int j)     // put item on top of stack
      { stackArray[++top] = j; }
//--------------------------------------------------------------
   public int pop()            // take item from top of stack
      { return stackArray[top--]; }
//--------------------------------------------------------------
   public int peek()           // peek at top of stack
      { return stackArray[top]; }
//--------------------------------------------------------------
   public boolean isEmpty()    // true if stack is empty
      { return (top == -1); }
//--------------------------------------------------------------
   public boolean isFull()     // true if stack is full
      { return (top == maxSize-1); }
//--------------------------------------------------------------
   public int size()           // return size
      { return top+1; }
//--------------------------------------------------------------
   public int peekN(int n)     // peek at index n
      { return stackArray[n]; }

   public void displayStack(String s)
      {
      System.out.print(s);
      System.out.print("Stack (bottom-->top): ");
      for(int j=0; j<size(); j++)
         {
         System.out.print( peekN(j) );
         System.out.print(' ');
         }
      System.out.println("");
      }

   } 

class ParsePost
   {
   private StackX theStack;
   private String input;
//--------------------------------------------------------------
   public ParsePost(String s)
      { input = s; }
//--------------------------------------------------------------
   public int doParse()
      {
      theStack = new StackX(20);             // make new stack
      char ch;
      int j;
      int num1, num2, interAns;

      for(j=0; j<input.length(); j++)       // for each char,
         {
         ch = input.charAt(j);              // read from input
         theStack.displayStack(""+ch+" ");  // *diagnostic*
         if(ch >= '0' && ch <= '9')         // if it's a number
            theStack.push( (int)(ch-'0') ); //   push it
         else                               // it's an operator
            {
            num2 = theStack.pop();          // pop operands
            num1 = theStack.pop();
            switch(ch)                      // do arithmetic
               {
               case '+':
                  interAns = num1 + num2;
                  break;
               case '-':
                  interAns = num1 - num2;
                  break;
               case '*':
                  interAns = num1 * num2;
                  break;
               case '/':
                  interAns = num1 / num2;
                  break;
               default:
                  interAns = 0;
               }  // end switch
            theStack.push(interAns);        // push result
            }  // end else
         }  // end for
      interAns = theStack.pop();            // get answer
      return interAns;
      } 
   }  

class PostfixApp
   {
   public static void main(String[] args) throws IOException
      {
      String input;
      int output;

      while(true)
         {
         System.out.print("Enter postfix: ");
         System.out.flush();
         input = getString();         // read a string from kbd
         if( input.equals("") )       // quit if [Enter]
            break;
                                      // make a parser
         ParsePost aParser = new ParsePost(input);
         output = aParser.doParse();  // do the evaluation
         System.out.println("Evaluates to " + output);
         }  
      }  

   public static String getString() throws IOException
      {
      InputStreamReader isr = new InputStreamReader(System.in);
      BufferedReader br = new BufferedReader(isr);
      String s = br.readLine();
      return s;
      }

   }  

至此表达式的计算就完成了,还是比较复杂的,需要完全理解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值