练习-栈在表达式求值中的应用

题目:输入字符串格式的算数表达式,计算出结果

思路:创建两个栈,一个栈用来存储数字,另一个栈用来存储运算符。然后从左到右遍历字符,遇到数字压入数字栈,遇到运算符需要与运算符栈的栈顶元素进行比较。
如果比栈顶运算符的优先级高,则直接入栈,如果比栈顶运算符的优先级低,或者优先级相同,则取出两个数字,一个运算符,进行完运算后将结果存入数字栈中,再将符号入栈。

1.未考虑表达式中包含括号的情况。

    public int calculate(String str) {
        char[] array = str.toCharArray();

        Stack numStack = new Stack<>();
        Stack symbolStack = new Stack<>();

        //存储运算符的等级
        HashMap map = new HashMap();
        map.put("*", 2);
        map.put("/", 2);
        map.put("+", 1);
        map.put("-", 1);

        // 进栈
        int result = 0;
        for (int i = 0; i < array.length; i++) {
            String chToStr = new String(array[i] + "");

            if (map.containsKey(chToStr)) {
                if (symbolStack.size() == 0) {
                    symbolStack.push(chToStr);
                    continue;
                }

                // 判断当前符号与栈顶符号的优先级
                String lastElement = symbolStack.peek();
                if (map.get(lastElement) >= map.get(chToStr)) {
                    // 计算,并将结果压栈
                    int num1 = Integer.parseInt(numStack.pop());
                    int num2 = Integer.parseInt(numStack.pop());
                    String sym = symbolStack.pop();

                    if ("*".equals(sym)) {
                        result = num1 * num2;
                    } else if ("/".equals(sym)) {
                        result = num2 / num1;
                    } else if ("+".equals(sym)) {
                        result = num2 + num1;
                    } else if ("-".equals(sym)) {
                        result = num2 - num1;
                    }

                    numStack.push(result + "");
                }
                symbolStack.push(chToStr);

            } else {
                //如果是数字,还要判断是不是个位数。如果不是个位数,需要进行拼接后再存储
                if (i > 0 && isNum(new String(array[i - 1] + ""))) { 
                    String pop = numStack.pop();
                    numStack.push(pop + chToStr);
                } else {
                    numStack.push(chToStr);
                }
            }
        }

        // 出栈
        int temp = 0;
        int size = symbolStack.size();
        for (int i = 1; i <= size; i++) {
            int num1 = Integer.parseInt(numStack.pop());
            int num2 = Integer.parseInt(numStack.pop());
            String sym = symbolStack.pop();

            if ("*".equals(sym)) {
                temp = num1 * num2;
            } else if ("/".equals(sym)) {
                temp = num2 / num1;
            } else if ("+".equals(sym)) {
                temp = num2 + num1;
            } else if ("-".equals(sym)) {
                temp = num2 - num1;
            }

            numStack.push(temp + "");
        }

        return Integer.parseInt(numStack.pop());

    }

    private boolean isNum(String str) {
        try {
            Integer.parseInt(str);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

2.考虑表达式中包含括号的情况。

    public int calculate(String str) {
        char[] array = str.toCharArray();

        Stack numStack = new Stack<>();
        Stack symbolStack = new Stack<>();

        HashMap map = new HashMap();
        map.put("(", 1);
        map.put("+", 2);
        map.put("-", 2);
        map.put("*", 3);
        map.put("/", 3);

        // 进栈
        for (int i = 0; i < array.length; i++) {
            String chToStr = new String(array[i] + "");

            if ("(".equals(chToStr)) { // 如果是左括号,直接进栈
                symbolStack.push(chToStr);
                continue;
            } else if (")".equals(chToStr)) { // 如果是右括号,两边都出栈,并进行计算,直到遇到左括号

                int size = symbolStack.size();
                for (int j = 0; j < size; j++) {
                    String sym = symbolStack.pop();
                    int num1 = Integer.parseInt(numStack.pop());
                    int num2 = Integer.parseInt(numStack.pop());

                    if ("(".equals(sym)) {
                        numStack.push(num2 + "");
                        numStack.push(num1 + "");
                        break;
                    }

                    int operation = operation(num1, num2, sym);

                    numStack.push(operation + "");
                }

            } else if (map.containsKey(chToStr)) {

                if (symbolStack.size() == 0) {
                    symbolStack.push(chToStr);
                    continue;
                }

                // 判断当前符号与栈顶符号的优先级
                String lastElement = symbolStack.peek();
                if (map.get(lastElement) >= map.get(chToStr)) {
                    // 计算,并将结果压栈
                    int num1 = Integer.parseInt(numStack.pop());
                    int num2 = Integer.parseInt(numStack.pop());
                    String sym = symbolStack.pop();

                    int res = operation(num1, num2, sym);

                    numStack.push(res + "");
                }
                symbolStack.push(chToStr);

            } else {
                if (i > 0 && isNum(new String(array[i - 1] + ""))) {
                    String pop = numStack.pop();
                    numStack.push(pop + chToStr);
                } else {
                    numStack.push(chToStr);
                }
            }
        }

        // 出栈
        int size = symbolStack.size();
        for (int i = 1; i <= size; i++) {
            int num1 = Integer.parseInt(numStack.pop());
            int num2 = Integer.parseInt(numStack.pop());
            String sym = symbolStack.pop();

            int res = operation(num1, num2, sym);

            numStack.push(res + "");
        }

        // System.out.println(numStack);
        // System.out.println(symbolStack);

        return Integer.parseInt(numStack.pop());

    }

    private int operation(int num1, int num2, String sym) {
        int temp = 0;

        if ("*".equals(sym)) {
            temp = num1 * num2;
        } else if ("/".equals(sym)) {
            temp = num2 / num1;
        } else if ("+".equals(sym)) {
            temp = num2 + num1;
        } else if ("-".equals(sym)) {
            temp = num2 - num1;
        }
        return temp;
    }

    private boolean isNum(String str) {
        try {
            Integer.parseInt(str);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

你可能感兴趣的:(练习-栈在表达式求值中的应用)