基于java的数据结构学习手记5——后缀表达式生成与计算

来源:互联网 发布:源码资本官网 编辑:程序博客网 时间:2024/05/17 09:27

 解释算术表达式:算术表达式,例如:4+5,3*4+7,(3+5)*(7-4),它用到的存储结构是栈。对于计算机的算法来说如果要直接求算术表达式的值,还是相当困难的。因此分两步实现算法会较容易。

1.将算术表达式转换成另一种形式:后缀表达式。

2.计算后缀表达式的值。

后缀表达式:日常算术表达式将操作符(operator)(+,-,*,/)放在两个操作数(operands)(数字,或代表数字的字母)之间的。因为操作符写在操作数的中间,所以把这种写法称为中缀表达法。例如2+3,5*7或者字母代替数字,如A+B,A/B等。在后缀表达式(也叫波兰逆序表达式Reverse Polish Notation RPN,由波兰数学家发明)中,操作符跟在两个操作数的后面,这样A+B就成为AB+,A/B成为AB/。更复杂的中缀表达式同样可以转换为后缀表达式。

将中缀表达式转化为后缀表达式的Java代码如下:

Code:
  1. package Stack;  
  2.   
  3. public class InToPost   //infix to postfix conversion  
  4. {  
  5. private infix theInfix;  
  6. private String input;  
  7. private String output="";  
  8. //...........................................................  
  9. public InToPost(String in)  //constructor  
  10. {  
  11.     input=in;  
  12.     int stackSize=input.length();  
  13.     theInfix=new infix(stackSize);  
  14. }  
  15. //...........................................................  
  16. public String doTrans() //do translation to postfix  
  17. {  
  18.     for(int j=0;j<input.length();j++)  
  19.     {  
  20.         char ch=input.charAt(j);  
  21.         theInfix.displayStack("For "+ch+" ");//diagnostic  
  22.         switch(ch)  
  23.         {  
  24.         case'+':  
  25.         case'-':  
  26.             gotOper(ch,1);  
  27.             break;  
  28.         case'*':  
  29.         case'/':  
  30.             gotOper(ch,2);  
  31.             break;  
  32.         case'(':  
  33.             theInfix.push(ch);  
  34.             break;  
  35.         case')':  
  36.             gotParen(ch);  
  37.             break;  
  38.         default:  
  39.             output=output+ch;  
  40.             break;  
  41.           
  42.         } //end switch  
  43.           
  44.     }  //end for  
  45. while(!theInfix.isEmpty())  
  46. {  
  47.    theInfix.displayStack("while");  
  48.    output=output+theInfix.pop();  
  49. }  
  50. theInfix.displayStack("End ");  
  51. return output;  
  52. }  
  53. //...........................................................  
  54. public void gotOper(char opThis,int prec1)  
  55. {  
  56.   while(!theInfix.isEmpty())  
  57.   {                              //got operator from input  
  58.       char opTop=theInfix.pop();  
  59.       if(opTop=='(')  
  60.       {  
  61.           theInfix.push(opTop);  
  62.           break;  
  63.       }  
  64.       else  
  65.       {  
  66.           int prec2;   //precedence of new op  
  67.           if(opTop=='+'||opTop=='-')  
  68.               prec2=1;  
  69.           else  
  70.               prec2=2;  
  71.           if(prec2<prec1)  
  72.           {  
  73.               theInfix.push(opTop);  
  74.               break;  
  75.           }  
  76.           else   
  77.               output=output+opTop;  
  78.       }//end else  
  79.         
  80.   }//end while  
  81. theInfix.push(opThis);//push new operator  
  82. }//end gotOp()  
  83. //...........................................................  
  84. public void gotParen(char ch)  
  85. {  
  86.     while(!theInfix.isEmpty())  
  87.     {  
  88.         char chx=theInfix.pop();  
  89.         if(chx=='(')break;  
  90.         else  
  91.             output=output+chx;  
  92.     }//end while  
  93. }    //end popOps()  
  94. //...........................................................  
  95. }//end class InToPost  

应用类创建一个InToPost对象,初始化参数是输入的字符串。接着带哦用对象的doTrans()方法执行转换。这个方法返回后缀表达式字符串,并显示返回结果。

 doTrans()方法用switch语句来出来输入字符串中的每个字符,当读到操作符时,它调用gotOper()方法,而读到右括号“)”时调用gotParen()方法,这些方法实现了对所有操作符的复杂规则。

       2.后缀表达的计算:

 后缀表达式的计算相对比较简单,所不同的是,这次就把操作数用栈保存起来,遇到操作符则取出栈顶的2个数计算后再入栈,依次直到操作符处理完全。计算后缀表达式的类如下:

  

Code:
  1. package Stack;  
  2.   
  3. public class ParsePost {  
  4.     private StackX theStack;  
  5.     private String input;  
  6. //...................................................  
  7.   public ParsePost(String s)  
  8.   {input=s;}  
  9. //...................................................  
  10.   public int doParse()  
  11.   {  
  12.       theStack=new StackX(20);  
  13.       char ch;  
  14.       int j;  
  15.       int num1,num2,interAns;  
  16.         
  17.       for(j=0;j<input.length();j++)  
  18.       {  
  19.           ch=input.charAt(j);  
  20.           theStack.displayStack("For "+ch+" ");  
  21.           if(ch>='0'&&ch<='9')  
  22.               theStack.push((int)(ch-'0'));  
  23.           else  
  24.           {  
  25.               num2=theStack.pop();  
  26.               num1=theStack.pop();  
  27.               switch(ch)  
  28.               {  
  29.               case'+':  
  30.                   interAns=num1+num2;  
  31.                   break;  
  32.               case'-':  
  33.                   interAns=num1-num2;  
  34.                   break;  
  35.               case'*':  
  36.                   interAns=num1*num2;  
  37.                   break;  
  38.               case'/':  
  39.                   interAns=num1/num2;  
  40.                   break;  
  41.                   default:  
  42.                       interAns=0;  
  43.               }//end switch  
  44.               theStack.push(interAns);  
  45.           }//end else  
  46.             
  47.       }//end for  
  48.         
  49.    return theStack.pop();  
  50.   }//end doParse()  
  51. }//end class parsePost  

其应用类如下:

Code:
  1. package Stack;  
  2.     import java.io.BufferedReader;  
  3.     import java.io.IOException;  
  4.     import java.io.InputStreamReader;  
  5.   
  6.     public class PostfixApp {  
  7.   
  8.         /** 
  9.          * @param args 
  10.          */  
  11.         public static void main(String[] args)throws IOException  
  12.         {  
  13.             // TODO Auto-generated method stub  
  14.             String input;  
  15.             int output;  
  16.             while(true)  
  17.             {  
  18.                 System.out.print("Enter Postfix: ");  
  19.                 System.out.flush();  
  20.                 input=getString();  
  21.                 if(input.equals(""))break;  
  22.                 ParsePost theParse=new ParsePost(input);  
  23.                 output=theParse.doParse();  
  24.                 System.out.println("Evaluates to: "+output+'/n');  
  25.             }//end while  
  26.         }//end main  
  27.         //...........................................................  
  28.     public static String getString()throws IOException    
  29.     {  
  30.         InputStreamReader in=new InputStreamReader(System.in);  
  31.         BufferedReader br=new BufferedReader(in);  
  32.         String s=br.readLine();  
  33.         return s;  
  34.         }  
  35.     }//end stackApps  

计算结果如下:

Code:
  1. Enter Postfix: 345+*612+/-  
  2. For 3 Stack(bottom->top):   
  3. For 4 Stack(bottom->top):3    
  4. For 5 Stack(bottom->top):3 4    
  5. For + Stack(bottom->top):3 4 5    
  6. For * Stack(bottom->top):3 9    
  7. For 6 Stack(bottom->top):27    
  8. For 1 Stack(bottom->top):27 6    
  9. For 2 Stack(bottom->top):27 6 1    
  10. For + Stack(bottom->top):27 6 1 2    
  11. For / Stack(bottom->top):27 6 3    
  12. For - Stack(bottom->top):27 2    
  13. Evaluates to: 25  
  14.   
  15. Enter Postfix: