import java.util.*;
import java.util.Stack;
public class Three {
   
    public static void main(String[] args){
   
        Double result = Calculate.result("(3+1)+1/3+9");
        System.out.println(result);
    }
}

class Calculate {
   
    //计算结果
    public static Double result(String str) {
   
        List<String> strList = strToStrList(str);
        List<String> postList = toPostOrder(strList);
        Double result = getResult(postList);
        return result;
    }
    //将字符串转换为字符串List
    private static List<String> strToStrList(String str) {
   
        List<String> strList = new ArrayList<>();
        int begin=0,end=0,post=0,i=0;
        for (; i < str.length(); i++) {
   
            if (str.charAt(i) == '+' || str.charAt(i) == '-' || str.charAt(i) == '*'
                || str.charAt(i) == '/' || str.charAt(i) == '(' || str.charAt(i) == ')') {
   
                end = i;
                if (begin < end) {
   
                    strList.add(str.substring(begin, end));
                    strList.add(str.substring(i,i+1));
                }
                //连续符号时
                else {
   
                    strList.add(str.substring(i,i+1));
                }
                begin = i + 1;
            }
        }
        //如果没有if包裹,当最后一个字符为操作符时,List末尾会添加一个空字符串
        if (!"".equals(str.substring(begin, str.length()))){
   
            strList.add(str.substring(begin, str.length()));
        }
        return strList;
    }
    /* 将中缀表达式转换为后缀表达式 */
    private static List<String> toPostOrder(List<String> strList) {
   
        /*规则: 53 *1,运算数直接输出 54 *2,左括号压入堆栈 55 *3,右括号 将栈顶的运算符弹出并输出,括号出栈不输出 56 *4,运算符: 57 * 若优先级大于栈顶运算符,压入栈 58 * 若优先级小于或等于栈顶运算符,栈顶运算符弹出并输出, 59 * 继续和新栈顶比较,直到比栈顶运算符优先级大,将它压入栈 60 *5,对象处理完毕后,将栈中运算符弹出并输出 61 */
        Stack<String> operStack = new Stack<>();
        List<String> postList = new ArrayList<>();
        for (int i = 0; i < strList.size(); i++) {
   
            if (isOper(strList.get(i), i, strList)) {
   
                //堆栈为空时操作符直接入栈
                if (operStack.isEmpty()) {
   
                    operStack.push(strList.get(i));
                } else {
   
                    //操作符为"("时直接入栈
                    if ("(".equals(strList.get(i))) {
   
                        operStack.push(strList.get(i));
                    } else if (")".equals(strList.get(i))) {
   
                        //操作符为")"时栈顶出栈并输出,直到遇到"(", "("出栈,")"不入栈
                        while (!"(".equals(operStack.peek())) {
   
                            postList.add(operStack.pop());
                        }
                        operStack.pop();
                    } else {
   
                        //其他操作符需要比较与栈顶元素的优先级
                        if ("(".equals(operStack.peek())) {
   
                            operStack.push(strList.get(i));
                        } else {
   
                            //优先级高,直接入栈
                            if (!operStack.isEmpty() && getPriority(strList.get(i)) > getPriority(operStack.peek())) {
   
                                operStack.push(strList.get(i));
                            } else {
   
                                if (!operStack.isEmpty() && getPriority(strList.get(i)) <= getPriority(operStack.peek()) && !"(".equals(operStack.peek())){
   

                                }
                                //优先级低或者相等,栈顶元素出栈,直到优先级比栈顶元素高
                                while (!operStack.isEmpty() && getPriority(strList.get(i)) <= getPriority(operStack.peek()) && !"(".equals(operStack.peek())) {
   
                                    postList.add(operStack.pop());
                                }

                                if (operStack.isEmpty()) {
   
                                    //若堆栈元素全部被弹出,直接入栈
                                    operStack.push(strList.get(i));
                                } else if (getPriority(strList.get(i)) > getPriority(operStack.peek()) || "(".equals(operStack.peek())) {
   
                                    //若优先级高,入栈
                                    operStack.push(strList.get(i));
                                }
                            }
                        }
                    }
                }
            } else {
   
                //操作数直接添加
                if ("-".equals(strList.get(i))){
   

                }else if (i >= 2 && "-".equals(strList.get(i - 1)) && "(".equals(strList.get(i - 2)) ) {
   
                    postList.add(strList.get(i - 1) + strList.get(i));
                } else if (i == 1 && "-".equals(strList.get(i - 1))) {
   
                    postList.add(strList.get(i - 1) + strList.get(i));
                } else {
   
                    postList.add(strList.get(i));
                }
            }
        }
        //最后将所有元素出栈
        while (!operStack.isEmpty()) {
   
            postList.add(operStack.pop());
        }
        return postList;
    }
    /** * 计算后缀表达式 */
    private static double getResult(List<String> postList) {
   
        /*规则: 157 *中缀表达式不用比较优先级 158 *将运算数入栈,每读到一个运算符 159 *就弹出栈顶的两个运算数,运算完毕后将结果压入栈 160 */
        Stack<String> numStack = new Stack();
        for(int i =0 ; i < postList.size(); i++) {
   
            if (isNum(postList.get(i))) {
   
                numStack.push(postList.get(i));
            } else if (isOper(postList.get(i), i, postList)) {
   

                if ("+".equals(postList.get(i))) {
   
                    Double num2 = Double.parseDouble(numStack.pop());
                    Double num1 = Double.parseDouble(numStack.pop());
                    Double result = num1 + num2;
                    numStack.push(result.toString());
                } else if ("-".equals(postList.get(i))) {
   
                    Double num2 = Double.parseDouble(numStack.pop());
                    Double num1;
                    //能计算负数开头
                    if (numStack.isEmpty()) {
   
                        num1 = 0.0;
                    } else {
   
                        num1 = Double.parseDouble(numStack.pop());
                    }
                    Double result = num1 - num2;
                    numStack.push(result.toString());
                } else if ("*".equals(postList.get(i))) {
   
                    Double num2 = Double.parseDouble(numStack.pop());
                    Double num1 = Double.parseDouble(numStack.pop());
                    Double result = num1 * num2;
                    numStack.push(result.toString());
                } else if ("/".equals(postList.get(i))) {
   
                    Double num2 = Double.parseDouble(numStack.pop());
                    Double num1 = Double.parseDouble(numStack.pop());
                    Double result = num1 / num2;
                    numStack.push(result.toString());
                }
            }
        }
        return Double.parseDouble(numStack.pop());
    }
    /* 判断该字符串是否为操作符 */
    private static boolean isOper(String str, int i, List<String> stringList){
   
        if("*".equals(str)|| "/".equals(str)||
                "+".equals(str)||
                "(".equals(str)|| ")".equals(str)){
   
            return true;
        } else if ("-".equals(str)) {
   
            return !(i>=1 && "(".equals(stringList.get(i-1)));
        }
        else{
   
            return false;
        }
    }
    /* 判断该字符串是否为操作数 */
    private static boolean isNum(String str){
   
        if("*".equals(str)|| "/".equals(str)||
                "+".equals(str)|| "-".equals(str)||
                "(".equals(str)|| ")".equals(str)){
   
            return false;
        }
        else{
   
            return true;
        }
    }
    /* 得到操作符的优先级 */
    private static int getPriority(String c){
   
        if("*".equals(c) || "/".equals(c)){
   
            return 2;
        } else if ("+".equals(c) || "-".equals(c)){
   
            return 1;
        } else {
   
            return 999;
        }
    }
}