Algs4-1.3.10中序表达式转为后序表达式(第二次实现)

1.3.10编写一个过滤器InfixToPostfix,将算术表达式由中序表达式转为后序表达式。
 答:本次做这个题时离上次做这个题有一个半月了,已经忘记了当时的算法。经过两个小时的研究(远低于第一次的研究时间),得出的算法与上次的算法几乎相同,个别细节有差别,而这个细节正是上一个版本的错误之处。
本次的算法描述如下:
前提:将读入的符分为三类:
1)操作数
2)运算符:运算符有+、-、*、/,^(指数运算)优先级+-相同,*/相同,-小于*,*小于^
3)左括号"("、右括号")"
算法:
  有一个Queue和一个Stack结构。
 1)不断的读入数据,直到读入空字符串时结束读入。
    1.1)如果读入的是操作数,那么入队。
    1.2)如果读入的是运算符时
           1.2.1)栈为空时,读入的运算符入栈。
           1.2.2)栈有内容时
                     1.2.2.1)栈顶元素是左括号时,将读入的运算符入栈。
                     1.2.2.2)栈顶元素是运算符,并且其优先级低于本次读入的运算符优先级时,将读入的运算符入栈。
                     1.2.2.3)栈顶元素是运算符,并且其优先及高于或等于本次读入的运算符优先级时,
                                   1.2.2.3.1)如果栈顶元素 是左括号  或是  优先级大于读入运算符的运算符  或是 栈为空,那么不弹出,否则一直弹 出并将弹出元素入队。结束弹出后,将读入运算符入栈。
    1.3)如果读入的时左括号时,入栈。
    1.4)如果读入的是右括号,栈元素不断的弹出并将弹出元素入队,直到弹出一个左括号时结束弹出,左括号不入队。
 2)读入数据结束后,将栈中元素全部弹出,并将弹出元素入队。
 3)出队次序即是后序表达式次序。

输入中序表达式:
1
+
2
*
3
-
4
/
2
+
(
1
+
4
)
输出后序表达式:
1
2
3
*
+
4
2
/
-
1
4
+
+
图片

public class InfixToPostfix
{
   public static void main(String[] args)
   {
      Queue<String> q=new Queue<String>();
      Stack<String> s=new Stack<String>();
       OperatorManager op=new OperatorManager();
      while(!StdIn.isEmpty())
      {
          String item=StdIn.readString();

          if(item.equals("("))
              s.push(item);
          else if(item.equals(")"))
               while(true)
               {
                   String sItem=s.pop();
                   if(sItem.equals("("))
                       break;
                   else
                       q.enqueue(sItem);
               }
          else if(op.isOperator(item))
             {
                if(s.isEmpty())
                    s.push(item);
                else if(s.peek().equals("("))
                    s.push(item);
                else if(op.levelIsBig(item,s.peek()))
                   s.push(item);
                else
                {
                    while(true)
                      {
                       if (s.isEmpty())
                           break;
                       else if(s.peek().equals("(")) 
                           break;
                       else if(op.levelIsBig(item,s.peek()))
                           break;
                       else
                           q.enqueue(s.pop());
                     }
                    s.push(item);
                }
             }
          else//is number
            q.enqueue(item);
         
          show(item,q,s);
      }//end read
      //element of Stack pop to queue.
      while(!s.isEmpty())
          q.enqueue(s.pop());
        show("",q,s);
      //show the express of postfix
       for(String i:q)
          StdOut.println(i);
    }//end main
   private static void show(String item,Queue<String> q,Stack<String> s)
   {
     StdOut.printf(item);
       StdOut.printf("   Queue:");      
    for(String i:q)
        StdOut.printf(i);
    StdOut.printf("   Stack:");
    for(String i:s)
        StdOut.printf(i);
    StdOut.println();
   }
      
}//end class


       public  class OperatorManager
       {
               private class Operator
               {
                   String OP;
                   int level;
               }
           private Operator[] a=new Operator[5];
           public OperatorManager()
            {
              Operator op0=new Operator();
              op0.OP="+";
              op0.level=0;
              a[0]=op0;
              //
              Operator op1=new Operator();
              op1.OP="-";
              op1.level=0;
              a[1]=op1;
              //
              Operator op2=new Operator();
              op2.OP="*";
              op2.level=1;
              a[2]=op2;
              //
              Operator op3=new Operator();
              op3.OP="/";
              op3.level=1;
              a[3]=op3;
              //
              Operator op4=new Operator();
              op4.OP="^";
              op4.level=2;
              a[4]=op4;
           }
    
           public boolean isOperator(String item)
           {
                for(int i=0;i<a.length;i++)
                    if(a[i].OP.equals(item))    return true;     
                return false;
           }
           public boolean levelIsBig(String op1,String op2)
           {
               int op1level=Level(op1);
               int op2level=Level(op2);
               return op1level>op2level;
           }
           private int Level(String op)
           {
               for(int i=0;i<a.length;i++)
               {
                   if(a[i].OP.equals(op))
                   return a[i].level;            
               }
               return -1;
           }
       }

posted @ 2018-10-25 13:48  修电脑的龙生  阅读(368)  评论(0编辑  收藏  举报