• 中缀表达式转后缀表达式


    具体步骤

    1. 初始化两个栈:运算符栈s1和储存中间结果的栈s2 在实际过程中,s2没有涉及到出栈操作,所以可以直接使用list代替(这样方便逆序);

    2. 从左到又扫描中缀表达式;

    3. 遇到操作数时,将其压如s2;

    4. 遇到运算符时,比较其与s1栈顶运算符的优先级:

      4.1. 如果s1为空,或栈顶运算符为左括号"(",则直接将此运算符入栈;

      4.2. 否则,若优先级比栈顶运算符的高,也将运算符压入s1中;

      4.3. 否则,将s1栈顶的运算符弹出并压入到s2中,再次转到4.1与s1中新栈顶运算符比较;

    5. 遇到括号时:

      5.1. 如果是"(",直接压入s1;

      5.2. 如果是")",则一次弹出s1的栈顶元素,并压入s2,直到遇上"("为止,此时将这一对括号丢弃

    6. 重复2到5,直到表达式到达最右边

    7. 将s1中剩余的运算符依次弹出并压入s2

    8. 依次弹出s2中的元素并输出,结果的逆序即为中缀表达式对应的后缀表达式.

    代码实现

    public class infixToSuffix {
        public static void main(String[] args) {
            //定义一个中缀表达式
            String expression = "1+((2+3)*4)-5";
            //先将中缀表达式转换成list,方便操作
            List<String> infixList = inFixToList(expression);
            System.out.println("中缀表达式list = "+infixList);
            //将中缀表达式转换成后缀表达式
            List<String> suffixList = infixToSuffixList(infixList);
            System.out.println("后缀表达式list = "+suffixList);
        }
    
        /**
         * 将中缀表达式转换成后缀表达式
         * @param infixList 中缀表达式的list
         * @return
         */
        private static List<String> infixToSuffixList(List<String> infixList) {
            //初始化一个栈,存放符号
            Stack<String> stack = new Stack();
            //初始化一个数组存放结果(分析使用的栈,因为没有出栈操作,所以不需要使用栈实现,直接用list更加方便)
            List<String> suffixList = new ArrayList<>();
            for (String s : infixList) {
                //如果是数字,直接添加到结果list中
                if (s.matches("\d+")){
                    suffixList.add(s);
                }else if (s.equals("(")){ //如果是"(" 直接入符号栈
                    stack.push(s);
                }else if (s.equals(")")){ //如果是")",则需要把符号栈中的符号出栈,把运算符添加到结果list中,直到匹配到"(",且"("出栈
                    while (!stack.peek().equals("(")){
                        suffixList.add(stack.pop());
                    }
                    //出栈"("
                    stack.pop();
                }else { //如果是运算符,则需要比较优先级
                    //栈中运算符的优先级大于等于当前的,则出栈,且添加到结果list中
                    while (stack.size() !=0 && Priority.getPriority(s)<=Priority.getPriority(stack.peek())){
                        suffixList.add(stack.pop());
                    }
                    //栈中运算符的优先级小于当前的,入栈
                    stack.push(s);
                }
    
            }
            //将栈中剩余的运算符取出,添加到结果list中
            while (stack.size()!=0){
                suffixList.add(stack.pop());
            }
            return suffixList;
        }
    
        /**
         * 将中缀表达式转换成list
         * @param expression
         * @return
         */
        private static List<String> inFixToList(String expression) {
            List<String> infixList = new ArrayList<>();
            int index = 0;  //遍历字符串指针
            String str = "";  //合并多位数
            char ch;
            //数字的ASCII 49~57
            while (index < expression.length()){
                ch = expression.charAt(index);
                //字符不是数字
                if (ch < 49 || ch > 57){
                    infixList.add(""+ch);
                    index ++;
    
                }else {
                    //是数字,判断是否为多位数,是就拼接
                    //拼接之前,先置空
                    str = "";
                    while (index<expression.length() && (ch=expression.charAt(index))>=49 &&
                            (ch=expression.charAt(index))<=57){
                        str+=ch;
                        index ++;
    
                    }
                    infixList.add(str);
                }
    
            }
            return infixList;
        }
    }
    
    class Priority{
        //这里只考虑加减乘除
        private static final int ADD = 1;
        private static final int SUB = 1;
        private static final int MUL = 2;
        private static final int DIV = 2;
    
        /**
         *
         * @param op 操作符
         * @return返回优先级
         */
        public static int getPriority(String op){
            int res = 0;
            switch (op){
                case "+":
                    res = ADD;
                    break;
                case "-":
                    res = SUB;
                    break;
                case "*":
                    res = MUL;
                    break;
                case "/":
                    res = DIV;
                    break;
                default:
                    break;
            }
            return res;
        }
    }
    
  • 相关阅读:
    CSS 3中细线边框如何实现?
    【SPL标准库专题(1)】 SPL简介
    【PSR规范专题(5)】PSR-4 改进后的自动加载规范
    【PSR规范专题(4)】PSR-3 日志接口规范
    【PSR规范专题(3)】PSR-2 代码风格规范
    【PSR规范专题(2)】PSR-1 基本代码规范
    YII框架的依赖注入容器与服务定位器简述
    PHP 反射机制Reflection
    【Apache运维基础(5)】Apache的Rewrite攻略(2)
    【Apache运维基础(4)】Apache的Rewrite攻略(1)
  • 原文地址:https://www.cnblogs.com/liuzhidao/p/13798804.html
Copyright © 2020-2023  润新知