首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > JAVA > J2SE开发 >

暑假在家闲得要命,写了个简单的算术式解析器,大家来批评一下吧,该怎么处理

2012-01-03 
暑假在家闲得要命,写了个简单的算术式解析器,大家来批评一下吧classNode E {//o:objectpublicEo//p:pri

暑假在家闲得要命,写了个简单的算术式解析器,大家来批评一下吧
class   Node <E> {

    //o:object
    public   E   o;
    //p:priority
    public   int   p;
    //l:left,r:right
    public   Node   l,r;
   
    public   Node(E   o){
        this.o   =   o;
    }
}

class   Stack <E> {

    private   Node   cur;
    private   int   size   =   0;
   
    public   void   push(E   o){
        Node <E>   n   =   new   Node <E> (o);
        if(cur!=null){
            cur.r   =   n;
            n.l   =   cur;
        }
        cur   =   n;
        size++;
    }
   
    public   E   pop(){
        if(size==0)
            return   null;
        try{
            size--;
            return   (E)cur.o;
        }finally{
            cur   =   cur.l;
            if(cur!=null)
                cur.r   =   null;
        }
    }
   
    public   int   size(){
        return   size;
    }
}

class   Tree{

    private   Node <String>   cur,root,start;
    private   Stack <Node>   nodes;
    private   String   s[],result;
   
    public   void   insert(String   s[]){
   
        if(s.length <=2)
            return;
        int   x   =   Parser.X_INIT;
        nodes   =   new   Stack <Node> ();
       
        //create   a   root   in   order   to   get   a   start
        //and   solve   the   condition   of   starting   with   "( "
        cur   =   new   Node <String> (Parser.operators[0]);
        cur.l   =   new   Node <String> ( "0 ");
        cur.p   =   Parser.p(Parser.operators[0])+x;
        root   =   cur;
        start   =   root;
       
        for(int   i=0;i <s.length;i++){
           
            //a   new   node
            Node <String>   n   =   new   Node <String> (s[i]);
           


            //while   s   is   ()   ,   increase   or   decrease   its   priority
            x   +=   s[i].equals( "( ")?Parser.X_STEP:s[i].equals( ") ")?-Parser.X_STEP:0;
           
            if(Parser.isOperator(s[i])){
           
                n.p   =   Parser.p(s[i])+x;
               
                //while   this   node 's   priority   is   less   than   the   previous '  
                //then   roll   back
                while(cur.p> n.p)
                    rollBack();
               
                //while   this   node 's   priority   is   bigger   than   the   previous '  
                //then   connect   this   to   the   right   child
                //and   move   the   origin   right   child   to   its   left   child
                if(cur.p <n.p){
                    nodes.push(cur);
                    n.l   =   cur.r;
                    cur.r   =   n;
               
                //while   this   node 's   priority   is   the   same   as   the   previous '
                //then   connect   its   left   child   with   the   previous '
                //and   move   the   parent   connect   from   the   previous '   to   this
                }else   if(cur.p==n.p){
                    n.l   =   cur;
                    if(nodes.size()==0)
                        root   =   n;
                }
               
                cur   =   n;
           
            //while   this   node   is   a   number
            //then   connect   it   to   the   current   node 's   right   child
            }else   if(java.util.regex.Pattern.matches( "(\\d+\\.\\d+)|\\d+ ",s[i])){
                cur.r   =   n;


            }
        }
       
        //rollback   at   end
        while(nodes.size()> 0)
            rollBack();
       
        //remove   the   temp   start:
        //find   the   node   which   left   child   is   the   temp   start
        //then   connect   its   left   child   to   the   temp   start 's   right   child
        if(start==root){
            root   =   start.r;
        }else{
            cur   =   root;
            while(cur.l.l.l!=null)
                cur   =   cur.l;
            cur.l   =   cur.l.r;
        }
           
    }
   
    //roll   back   to   the   parent   tree
    private   void   rollBack(){
        Node <String>   temp   =   nodes.pop();
        temp.r   =   cur;
        cur   =   temp;
        if(nodes.size()==0)
            root   =   temp;
    }
   
    //iterate   the   tree   prefixally
    public   String   prefix(){
        result   =   " ";
        prefixIterate(root);
        return   result;
    }
    private   void   prefixIterate(Node   n){
        if(n==null)
            return;
        result   +=   n.o+ "   ";
        prefixIterate(n.l);
        prefixIterate(n.r);
    }

    //iterate   the   tree   postfixally
    public   String   postfix(){
        result   =   " ";
        postfixIterate(root);
        return   result;
    }
    private   void   postfixIterate(Node   n){
        if(n==null)
            return;
        postfixIterate(n.l);
        postfixIterate(n.r);
        result   +=   n.o+ "   ";
    }
}

class   Calculator{
   
    //get   the   result   from   postfix   expression
    public   static   double   calculateInPostfix(String   s[]){
        Stack <Double>   num   =   new   Stack <Double> ();
        double   result   =   0;


        for(int   i=0;i <s.length;i++)
            if(Parser.isOperator(s[i])){
                double   d1   =   num.pop();
                double   d2   =   num.pop();
                result   =   calculate(d1,d2,s[i]);
                num.push(result);
            }else{
                num.push(Double.parseDouble(s[i]));
            }
        return   num.pop();
    }
   
    //the   calculate   rule
    //you   can   add   your   rule   here   < < < < < < < < < < < < < < < < < < < < < < <
    public   static   double   calculate(double   d1,double   d2,String   operator){
        double   result   =   0;
        if(operator.equals( "+ ")){
            result   =   d2+d1;
        }else   if(operator.equals( "- ")){
            result   =   d2-d1;
        }else   if(operator.equals( "* ")){
            result   =   d2*d1;
        }else   if(operator.equals( "/ ")){
            result   =   d2/d1;
        }else   if(operator.equals( "^ ")){
            result   =   Math.pow(d2,d1);
        }else   if(operator.equals( "# ")){
            result   =   Math.pow(d2,1/d1);
        }
        return   result;
    }
}

public   class   Parser{
   
    //the   support   operators
    public   static   final   String   operators[]   =   new   String[]{ "+ ", "- ", "* ", "/ ", "^ ", "# "};
    //the   support   operators   in   regex
    public   static   final   String   operators2[]   =   new   String[]{ "\\+ ", "\\- ", "\\* ", "\\/ ", "\\^ ", "# "};
    //the   prioritie   of   the   operators
    //it   should   be   less   than   X_STEP
    public   static   final   int   priorities[]   =   new   int[]{2,2,4,4,6,6};
    //you   can   add   your   operator   in   upwards   3   arrays   < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < <
   
    //x:extension   priority
    //the   extension   priority   of   ()
    //X_INIT   is   the   initial   value


    //and   the   X_STEP   is   the   extension   priority;
    public   static   int   X_INIT   =   1,X_STEP   =   10;
   
    private   String   s[];
    private   Tree   t   =   new   Tree();
   
    public   Parser(String   s){
        this.s   =   parseSource(s.trim());
        t.insert(this.s);
    }
   
    //judge   if   it   is   an   operator
    public   static   boolean   isOperator(String   s){
        for(int   i=0;i <operators.length;i++)
            if(operators[i].equals(s))
                return   true;
        return   false;
    }
   
    //get   the   priority   fo   operator
    public   static   int   p(String   s){
        for(int   i=0;i <operators.length;i++)
            if(operators[i].equals(s))
                return   priorities[i];
        return   -1;
    }
   
    //hanle   the   source   string
    private   String[]   parseSource(String   s){
        String   rule   =   "[^\\d|\\(|\\)|\\. ";
        for(int   i=0;i <operators2.length;i++)
            rule   +=   "| "+operators2[i];
        rule   +=   "] ";
        s   =   s.replaceAll(rule, " ");
        for(int   i=0;i <operators2.length;i++)
            s   =   s.replaceAll(operators2[i], "   "+operators2[i]+ "   ");
        s   =   s.replaceAll( "\\( ", "(   ").replaceAll( "\\) ", "   ) ");
        return   s.split( "   + ");
    }

    public   double   calculate(){
        return   Calculator.calculateInPostfix(t.postfix().split( "   "));
    }
   
    //get   the   infix   expression
    public   String   converToInfix(){
        String   result   =   " ";
        for(int   i=0;i <s.length;i++)
            result   +=   s[i]+ "   ";
        return   result;
    }
   
    //get   the   prefix   expression
    public   String   converToPrefix(){
        return   t.prefix();
    }
   
    //get   the   postfix   expression
    public   String   converToPostfix(){
        return   t.postfix();


    }
   
    public   static   void   main(String   args[]){
        Parser   p   =   new   Parser( "(1+2.7)*3*(7+9)^(2#3)+1/5 ");
        System.out.println( "中缀表达式: "+p.converToInfix());
        System.out.println( "前缀表达式: "+p.converToPrefix());
        System.out.println( "后缀表达式: "+p.converToPostfix());
        System.out.println( "计算结果:     "+p.calculate());
    }
}

[解决办法]
不错不错~~
支持一下
不过这些东西网上应该都有了
可以写些应用的东西
花几天旅游也不错,难得放假~~

热点排行