zoukankan      html  css  js  c++  java
  • 3.中缀表达式转后缀表达式

    package com.vi.stack;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Stack;
    
    /**
     * 将中缀表达式转成后缀表达式
     * @author vi
     *
     */
    public class InfixToSuffixDemo {
        public static void main(String[] args) {
            String expression = "1+((2+3)*4)-5";
            //将表达式存储在List中
            List<String> target = changeToList(expression);
            System.out.println(target);
            //开始转换
            //s1运算符栈
            Stack<String> s1 = new Stack<String>();
            //s2 用list保存结果
            List<String> s2 = new ArrayList<String>();
            for(String item : target ) {
                //如果匹配到数字,存入s2
                if(item.matches("\d+")) {
                    s2.add(item);
                } else{
                        //匹配是非数字,判断是否"(",左括号直接入栈
                        if("(".equals(item)) {
                            s1.push(item);
                        } else if(")".equals(item)) {
                                //是否是")",是的话,需要比较栈顶元素是否(, 不是就弹出栈顶,存入s2中,直到栈顶为"(",然后消掉左括号
                                while(s1.size()>0 && !s1.peek().equals("(")) {
                                    s2.add(s1.pop());
                                }
                                s1.pop();
                            } else {
                                //比较运算符与栈顶元素的优先级,低于栈顶元素,将栈顶弹出加入list中,高于栈顶就压入栈
                                while(s1.size()>0 && priority(item) >= priority(s1.peek())) {
                                    s2.add(s1.pop());
                                } 
                                s1.push(item);
                            }
                        }
                    }
                //将s1栈中剩余的元素依次弹出,存到s2中
                while(s1.size() > 0)
                    s2.add(s1.pop());
                //打印s2,得到的就是转后缀表达式的结果
                System.out.println(s2);
            }
        
        
        /**
         * 将目标中缀表达式解析后,存储到list中
         * @param expression
         * @return
         */
        public static List<String> changeToList(String expression) {
            List<String> result = new ArrayList<String>();
            for(int i = 0 ; i < expression.length() ;i++) {
                String cur = expression.charAt(i)+"";
                //判断获得的是否是数字
                if(cur.matches("\d+")) {//如果是数字,还需要判断下一位是否为数字,是的话进行拼接之后再存储
                    int j = i+1;
                    //如果下标没有超过表达式长度,并且表达式中的是数字,则进行拼接
                    while(j<expression.length() && (expression.charAt(j)+"").matches("\d+")) {
                        cur = cur + expression.charAt(j)+"";
                        j++;
                    }
                    result.add(cur);
                    i = j - 1;
                } else {
                    //如果不是数字,直接存入list中
                    result.add(cur);
                }
            }
            return result;
        }
        
        /**
         * 返回目标字符串的优先级
         * @param target
         * @return
         */
        public static int priority(String target) {
            if("+".equals(target) || "-".equals(target)) {
                return 1;
            }
            else if("*".equals(target) || "/".equals(target)) {
                return 2;
            } else {//如果是括号
                return 3;
            }
        }
    }

    打印结果:

    步骤总结:

    1.准备两个栈,运算符栈s1,存储结果栈s2(可用链表代替)

    2.将目标表达式进行扫描

    3.如果扫描到数字,存入s2栈中

    4.如果扫描到运算符

      4.1 判断是否为"(",是的话直接入s1栈

      4.2 判断是否为")",是的话判断s1栈顶元素是否为"(",不是的话将s1栈顶元素弹出,压入s2栈中,并不断重复过程直到s1栈顶为"(",此时将"("弹出

      4.3 判断当前运算符和栈顶运算符的优先级(括号>* / > + -),如果优先级低于s1栈顶元素,将当前元素压入s1栈,否则将栈顶弹出,压入s2栈,然后将当前元素压入s1栈

    5.重复3、4步直至扫描完目标表达式,最后将s1栈中剩余元素弹出,依次压入s2栈中。

    6.将s2栈中元素弹出,逆序后的结果就是目标表达式对应的后缀表达式!!!

  • 相关阅读:
    新能源汽车三大核心技术
    新能源汽车分类解读
    hadoop(四):配置参数
    HDP2.4安装(六):小结与回顾
    【Web】Nginx配置开机启动
    【Linux】ODBC安装
    【Erlang】源码安装
    【Linux】 Ncures库的介绍与安装
    【RabbitMQ】 RabbitMQ安装
    《MinDoc 接口文档在线管理系统》
  • 原文地址:https://www.cnblogs.com/blogforvi/p/11521239.html
Copyright © 2011-2022 走看看