zoukankan      html  css  js  c++  java
  • java中的栈Stack的基本使用和应用(二) ——利用栈计算合法的算术表达,中缀表达式转后缀表达式

    利用栈Stack计算合法的算术表达式

    限定的算术表达式求值问题:包含  “+”、“-”、“*”、“/”  、正整数和圆括号的合法算术表达式。

    算术表达式转化成后缀表达式

    程序语言中,运算符在两个运算数中间称为中缀表达式,即我们常用的表达方法,例如 1+2*3。

    在中缀表达式中要考虑运算的优先级,先乘除,后加减,从左到右,还有括号内先运算。

    在后缀表达式中已经考虑了运算符的优先级,并且没有括号,只有运算数和运算符。

    例如上述例子 1+2*3 ,中缀表达式计算时,根据优先级,先计算2*3=6,再计算1+6=7

    转换成后缀表达式   1+2*3 => 123*+ ,

    从左到右扫描第一个运算符为 * ,先执行2*3;第二个运算符为 + ,执行1+6.

    中缀表达式转后缀表达式过程

    ①初始化exp字符数组、resultExp字符数组(可变)、operator栈

      exp字符数组:存放,合法的算术表达式

      resultExp字符数组(可变):存放后缀表达式

      operator栈:存放运算符,并将 “=” 作为栈底元素

    ②从exp读取字符ch,若为运算数将后续运算数依次存放入resultExp中,并以#标志数值结束

    ③若ch为运算符,将其和operator栈顶中的运算符进行比较优先级比较

      ch优先级大于栈顶运算符优先级,则ch进栈

      ch优先级小于栈顶运算符优先级,则栈中运算符退栈,直至ch运算符大于栈顶运算符,ch再进栈。

      ch优先级等于栈顶运算符优先级,特殊情况,只有括号满足该情况,即“)”的优先级 等于“(”的优先级,将(退栈。

    ④exp扫描完毕,此时operator栈不空,则将 “=” 之前所有的运算符退栈并放入resultExp中

    复杂一点的例子

    (12-3)/(4+5)

    算法如下:

    package com.xumz.stack;
    
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    import java.util.Stack;
    /**
     * 中缀表达式转后缀表达式
     * 
     * @author xumz 2017/10/18
     */
    public class ExpressionChange {
        // 存放左运算符的优先级
        Map<Character, Integer> leftOperator = new HashMap<Character, Integer>() {
            {
                put('=', 0);
                put('(', 1);
                put('+', 3);
                put('-', 3);
                put('*', 5);
                put('/', 5);
                put(')', 6);
            }
        };
        // 存放右运算符的优先级
        Map<Character, Integer> rightOperator = new HashMap<Character, Integer>() {
            {
                put('=', 0);
                put('(', 6);
                put('+', 2);
                put('-', 2);
                put('*', 4);
                put('/', 4);
                put(')', 1);
            }
        };
    
        /**
         * 中缀转后缀
         * 
         * @param str
         * @return
         */
        public String trans(String str) {
            // 转换成char[]
            char[] exp = str.toCharArray();
            // 存放转换结果
            List<Character> resultExp = new ArrayList<Character>();
            // 存放运算符,初始底为‘=’
            Stack<Character> operator = new Stack<Character>();
            operator.push('=');
            // 扫描exp表达式
            int i = 0;
            while (i != exp.length) {
                // 数字情况
                if (!isOperator(exp[i])) {
                    while (i != exp.length && !isOperator(exp[i])) {
                        resultExp.add(exp[i]);
                        i++;
                    }
                    resultExp.add('#');
                }
                // 运算符情况
                else {
                    switch (compareOperatorNice(operator.peek(), exp[i])) {
                    case -1:
                        operator.push(exp[i]);
                        i++;// 继续下一个字符
                        break;
                    case 0:
                        operator.pop();
                        i++;// 继续下一个字符
                        break;
                    case 1:
                        resultExp.add(operator.peek());
                        operator.pop();
                        break;
                    }
                }
    
            }
            while (!(operator.peek()=='=')) {
                resultExp.add(operator.peek());
                operator.pop();
            }
            
    
            // 转换为String返回
            return resultExp.toString();
        }
    
        boolean isOperator(char ch) {
            if (leftOperator.containsKey(ch)) {
                return true;
            }
            return false;
        }
    
        /**
         * 比较左右运算符优先级,返回状态结果
         * 
         * @param leftOperator
         * @param rightOperator
         * @return
         */
        int compareOperatorNice(char left, char right) {
            if (leftOperator.get(left) == rightOperator.get(right)) {
                return 0;
            }
            if (leftOperator.get(left) < rightOperator.get(right)) {
                return -1;
            }
            return 1;
        }
    
    }
    View Code
  • 相关阅读:
    带圈的数字,类似开票网站开奖号码
    wpf 获取Image的图片并保存到本地
    ashx获取Oracle数据库图片
    Ext选项卡tabpanel切换动态加载数据
    Windows10禁止优酷自动更新(亲测有用)
    数组指针和指针数组的区别
    学习:简谈前端后端
    再谈前后端分离开发和部署
    前端项目部署
    功能测试框架
  • 原文地址:https://www.cnblogs.com/xumz/p/7725053.html
Copyright © 2011-2022 走看看