美文网首页
练习-栈在表达式求值中的应用

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

作者: 麦兜的夏天 | 来源:发表于2019-05-29 11:42 被阅读0次

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

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

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

        public int calculate(String str) {
            char[] array = str.toCharArray();
    
            Stack<String> numStack = new Stack<>();
            Stack<String> symbolStack = new Stack<>();
    
            //存储运算符的等级
            HashMap<String, Integer> map = new HashMap<String, Integer>();
            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<String> numStack = new Stack<>();
            Stack<String> symbolStack = new Stack<>();
    
            HashMap<String, Integer> map = new HashMap<String, Integer>();
            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;
            }
        }
    

    相关文章

      网友评论

          本文标题:练习-栈在表达式求值中的应用

          本文链接:https://www.haomeiwen.com/subject/srpetctx.html