import java.util.Scanner;

/*
2012年11月17日 11:34:10
高级计算器
覃唐弢
 * example:
{2.2-2/[3-(34-32)+2.3]+2.2}+2.3
  *  1.2*{2.2-2/[3-(34-32)+2.3]+2.2}+2.3=6.852727272727273
 * */

public class Counter {
    public static void main(String[] args) {
        String expreStr = null;
        System.out.print("请输入计算表达式:");
        Scanner in = new Scanner(System.in);
        expreStr = in.next();
        Expression expr = new Expression(expreStr);
        double result = expr.start();
        System.out.println(expreStr+"="+result);
    }
}

//表达式处理类
class Expression{
    private String expreStr="";
    private String temp = "";
    private int index = 0; //截取字符的下标位置 
    private int len= 0 ;//表达式长度
    private double num1,num2,result;
    private char oper;
    private OperStack operStack = new OperStack(); //操作符栈
    private NumStack numStack  = new NumStack(); //操作数栈
    public Expression(String expreStr){
        this.expreStr = expreStr;
        this.len = this.expreStr.length();
    }
    
    //主运算
    public double start(){
        while(index<len){ 
            //判断一个数的最前面的位 不能是小数点 .
            if(this.isOper(this.getNextChar())==-1){
                System.err.println("小数点不能在一个数的最前面,如[.123]");
                System.exit(0);
            }
            temp+=this.truncate();
            char c = temp.toString().toCharArray()[0];    
            //是操作符 入操作符栈
            if(isOper(c)>0){
                //是空 则直接入栈
                if(this.operStack.isEmpty()){
                    this.operStack.push(c);
                }else{
                    //当前 操作符是-+/*就去判断优先级  否则直接入栈
                    if(isOper(c)==1){
                        //如果栈顶是 ( 则直接入栈  1{-,+}  2{*, /}
                        if(this.operStack.priority(this.operStack.getTop())!=0){
                            //判断优先级
                            //1.1小于等于  栈顶操作符   ---> 计算 完 后  再入栈 
                            //继续判断当前操作符 和 栈顶操作符的优先级
                            while(!this.operStack.isEmpty()&&this.operStack.priority(c)<=this.operStack.priority(this.operStack.getTop())){
                                this.operation();
                            }
                        }
                    }else if(isOper(c)==22){ // 是 ) 则运算 ( ) 之间的
                    
                        //取完后 则计算 栈中剩余的操作符
                        while(!this.operStack.isEmpty() && isOper(this.operStack.getTop())==1){
                            this.operation();
                        }
                        //此时 把 操作符栈顶 的 ( -->出栈
                        this.operStack.pop();
                    }else if(isOper(c)==33){ // 是 ] 则运算 [ ] 之间的
                        //取完后 则计算 栈中剩余的操作符
                        while(!this.operStack.isEmpty() && isOper(this.operStack.getTop())==1){
                            this.operation();
                        }
                        //此时 把 操作符栈顶 的 [ -->出栈
                        this.operStack.pop();
                    }else if(isOper(c)==44){ // 是 } 则运算 { } 之间的
                        //取完后 则计算 栈中剩余的操作符
                        while(!this.operStack.isEmpty() && isOper(this.operStack.getTop())==1){
                            this.operation();
                        }
                        //此时 把 操作符栈顶 的 { -->出栈
                        this.operStack.pop();
                    }
                    //1.2 大于 栈顶操作符   ---> 入栈
                    if(isOper(c)<=4)
                        this.operStack.push(c);
                }
            }else{
            //是操作数 入操作数栈
                int isManyPoint = 0;
                //应该继续判断下一个字符 是否也为数字 
                while(index<len && (this.isOper(this.getNextChar())==0 || this.isOper(this.getNextChar())==-1)){
                //是数字 
                    if(this.isOper(this.getNextChar())==-1){
                        isManyPoint++;
                    }
                    if(isManyPoint>=2){ //如果一个数中有多个小数点 则退出
                        System.err.println("一个数不能有多个小数点,如[12.23.23]");
                        System.exit(0);
                    }
                    temp+=this.truncate();
                }
                try{
                    this.numStack.push(Double.parseDouble(temp));
                } catch (Exception e) {
                    System.err.println("表达式输入不正确!!");
                    return 0;
                }
            }
            temp="";//清空
        }
        
        //取完后 则计算 栈中剩余的操作符
        while(!this.operStack.isEmpty()){
            this.operation();
        }
        //操作数 此时 只有一个元素 即结果
        return this.numStack.pop();
    }
    
    //取出操作数栈顶两个数  和 操作负  并运算  把结果放入操作数栈
    public void operation(){
        oper = this.operStack.pop();
        num1 = this.numStack.pop();
        num2 = this.numStack.pop();
        result = this.numStack.operation(num1, oper, num2);
        //计算完后 把结果放入 操作数栈顶
        this.numStack.push(result);
    }
    
    //取得字符串[操作符、操作数]
    public String truncate(){
        return this.expreStr.substring(index++, index);
    }
    
    //如果当前是数字 则获取下一个是否也为数字  12
    public char getNextChar(){
        String temp = this.expreStr.substring(index, index+1);
        char c = temp.toCharArray()[0];    
        return c;
    }
    
    //判断是否为操作符
    public int isOper(char oper){
        switch(oper){
            case '-':
            case '+':
            case '/':
            case '*':
                return 1;
            case '(':
                return 2;
            case '[':
                return 3;
            case '{':
                return 4;
            case ')':
                return 22;
            case ']':
                return 33;
            case '}':
                return 44;
            case '.':
                return -1;
            default: //是数字
                return 0;
        }
    }
}

//操作符栈
class OperStack{
    private char operStack[] = new char[100];  
    private int index = 0;
    //放入操作符
    public void push(char oper){
        this.operStack[index++] = oper;
    }
    //弹出栈顶操作符
    public char pop(){
        return this.operStack[--index];
    }
    //取得栈顶操作符
    public char getTop(){
        return this.operStack[index-1];
    }
    //判断是否为空
    public boolean isEmpty(){
        if(index<=0)
            return true;
        return false;
    }
    //比较操作符的优先级
    public int priority(char oper){
        switch(oper){
            case '-':
            case '+':
                return 1;
            case '/':
            case '*':
                return 2;
            default:
                return 0;
        }
    }
    
}
//操作数栈
class NumStack{
    private double numStack[] = new double[100];
    private int index = 0;
    //放入操作符
    public void push(double num){
        this.numStack[index++] = num;
    }
    //弹出栈顶操作数
    public double pop(){
        return this.numStack[--index];
    }
    //取得栈顶操作数
    public double getTop(){
        return this.numStack[index-1];
    }
    //判断是否为空
    public boolean isEmpty(){
        if(index<=0)
            return true;
        return false;
    }
    //运算
    public double operation(double num1, char oper, double num2){
            switch(oper){
                case '-':
                    return num2-num1;
                case '+':
                    return num2+num1;
                case '/':
                    return num2/num1;
                case '*':        
                    return num2*num1;
                default:
                    return 0;
            }
    }
}