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());
  }
}

解决方案 »

  1.   

    放假写点小玩意,总比天天在CSDN里看黄色笑话的好记得很久以前这里有人问过,有位兄台说丢给数据库算,哈,真是聪明大家要是觉得有一点利用价值的话,就帮我顶一下吧^_^演示:
    ==========================================================
    C:\java>java Parser
    中缀表达式:( 1 + 2.7 ) * 3 * ( 7 + 9 ) ^ ( 2 # 3 ) + 1 / 5
    前缀表达式:+ * * + 1 2.7 3 ^ + 7 9 # 2 3 / 1 5
    后缀表达式:1 2.7 + 3 * 7 9 + 2 3 # ^ * 1 5 / +
    计算结果:  365.3061021526654
    ==========================================================另外,这个东西我做成可扩展的
    只要在Parser类里设置operators、operators2和priorities(优先级)
    再在Calculator类里添加相应的计算方法即可