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

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

作者: 麦兜的夏天 | 来源:发表于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;
        }
    }

相关文章

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

    题目:输入字符串格式的算数表达式,计算出结果 思路:创建两个栈,一个栈用来存储数字,另一个栈用来存储运算符。然后从...

  • 4 : 栈

    1:什么是栈 2:栈的存在意义 3:如何实现一个“栈”? 4:复杂度 5:栈在函数调用中的应用 6:栈在表达式求值...

  • 栈: 顺序栈 栈的应用:函数调用栈,表达式求值,括号匹配,浏览器的前进后退。相关code:https://gith...

  • 数据结构复习

    第三章 栈和队列 一 栈 栈的类型 顺序栈 链式栈 双向栈 栈的应用 数制转换 行编辑程序 迷宫求解 表达式求值:...

  • 数据结构入门(三)栈的应用

      在之前的两篇文章——数据结构入门(一)栈的实现和数据结构入门(二)栈的应用之数学表达式求值中,笔者分别介绍了“...

  • 【数据结构】【C#】011-栈的应用:📟表达式求值

    C#数据结构:栈的应用:表达式求值 后缀表达式 在我们日常生活中所见表达式都是中缀表达式,如 “5*(3+7)-4...

  • 大话数据结构 - 栈

    代码GitHub地址 栈的分类 栈是特殊的线性表 栈的典型应用递归,四则运算表达式求值。 栈的分类有两种: 静态栈...

  • 数据结构 第5节 栈 Stack

    一、静态栈:数组实现 二、动态栈:链表实现 三、应用: 生产者消费者 函数调用 中断 算术表达式求值 内存分配 缓...

  • 表达式求值

    表达式求值时对数据结构中栈结构的灵活应用,对于一个表达式而言,它由操作数和运算符组合而成,我们现实中常见的表达式:...

  • 20. 有效的括号

    题目 解析 这道题特别有意思,解法和Dijkstra双栈算法表达式求值类似,这题也是一个栈的应用。以字符串( { ...

网友评论

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

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