zoukankan      html  css  js  c++  java
  • 10、栈-中缀表达式转后缀表达式

    来源:https://www.bilibili.com/video/BV1B4411H76f?p=39

    一、思路

    1、初始化同样设置两个栈,符号栈s1和结果栈s2;

    2、从左到右扫描中缀表达式;

    3、遇到数据,直接入栈s2;

    4、遇到符号:

      4.1、如果s1为空,或者s1的栈顶符号为 "(" ,也就是左括号,直接入栈s1

      4.2、如果当前符号比s1栈顶的符号优先级高,直接入栈s1

      4.3、否则,将s1栈顶的那个运算符弹出,压入到s2,然后回到4.1继续比较,直到入栈。

    5、遇到括号:

      5.1、左括号"("直接入栈s1

      5.2、右括号")",将s1中的运算符依次弹出,入栈s2,直到遇到左括号"(",此时将括号删除

    6、重复步骤2-5,直到表达式结束

    7、将s1中剩余的符号弹出,入栈s2

    8、s2中的内容依次弹出,逆序,则为后缀表达式

    二、实现

    1、根据原始字符串的到中缀表达式对应的数组,要注意多位数的存在

     1     //根据原始字符串得到中缀表达式的字符串
     2     public static List<String> getInfixArray(String s){
     3         List<String> list = new ArrayList<>();
     4         int i = 0;//遍历原始的表达式
     5         char c;//获取当前位置的字符
     6         String keepNum;//如果是多位数可以用来拼接
     7         while (true){
     8             if((c = s.charAt(i)) < 48 || (c = s.charAt(i)) > 57){
     9                 //不是数字
    10                 list.add(""+c);
    11                 i++;
    12             }else {
    13                 keepNum = "";
    14                 while (i < s.length() && (c = s.charAt(i))>= 48 && (c = s.charAt(i)) <= 57 ){
    15                     keepNum += c;
    16                     i++;
    17                 }
    18                 list.add(""+keepNum);
    19             }
    20             if(i > s.length() - 1){
    21                 break;
    22             }
    23         }
    24         return list;
    25     }

    测试

    1         //原始表达式
    2         String expression = "1+((2+3)*4)-5";
    3         //根据原始表达式得到中缀表达式
    4         List<String> infixArray = getInfixArray(expression);
    5         System.out.println(infixArray);

    结果

    [1, +, (, (, 2, +, 3, ), *, 4, ), -, 5]

    2、按照思路将中缀表达式转化为后缀表达式(这里为了方便,将结果栈s2定义为数组,不必进行弹出后再倒序)。同时,定义了一个判断符号优先级的方法。

     1     public static List<String> infixToSuffix(List<String> infix){
     2         //符号栈
     3         Stack<String> s1 = new Stack<String>();
     4         //结果,由于后期需要逆序得到结果,这里用数组
     5         List<String> s2 = new ArrayList<>();
     6 
     7         for (String item : infix) {
     8             if(item.matches("\d+")){
     9                 //如果是一个数字
    10                 s2.add(item);
    11             }else if(item.equals("(")){
    12                 //左括号,入符号栈
    13                 s1.push(item);
    14             }else if(item.equals(")")){
    15                 //右括号,直到找到左括号
    16                 while (!s1.peek().equals("(")){
    17                     s2.add(s1.pop());
    18                 }
    19                 s1.pop();//弹出左括号
    20             }else {
    21                 //不为空,且优先级小于等于栈顶的
    22                 while (s1.size() != 0 && properties(item) <= properties(s1.peek())){
    23                     s2.add(s1.pop());
    24                 }
    25                 //否则,直接入栈
    26                 s1.push(item);
    27             }
    28         }
    29 
    30         //表达式遍历完成,s1出栈加入到s2
    31         while (!s1.isEmpty()){
    32             s2.add(s1.pop());
    33         }
    34         return s2;
    35     }
    36 
    37     //计算符号的优先级
    38     public static int properties(String oper){
    39         int res = 0;
    40         switch (oper){
    41             case "+":
    42                 res = 1;
    43                 break;
    44             case "-":
    45                 res = 1;
    46                 break;
    47             case "*":
    48                 res = 2;
    49                 break;
    50             case "/":
    51                 res = 2;
    52                 break;
    53             default:
    54                 System.out.println("运算符错误");
    55                 break;
    56         }
    57         return res;
    58     }

    测试

    1         //中缀转后缀
    2         List<String> suffix = infixToSuffix(infixArray);
    3         System.out.println(suffix);
    4         System.out.println();
    5 
    6         int res = calculate(suffix);
    7         System.out.println(res);

    结果

    运算符错误
    运算符错误
    [1, 2, 3, +, 4, *, +, 5, -]
    
    16
  • 相关阅读:
    Jmeter监控服务器性能
    三种主流的WebService实现方案(REST/SOAP/XML-RPC)简述及比较
    从0到1搭建移动App功能自动化测试平台(0):背景介绍和平台规划
    Jmeter监控系统等资源,ServerAgent端口的修改
    Performance plugin离线安装
    Oracle定义常量和变量
    通过FTP将一个数据文件从A服务器下载到B服务器的整个过程
    Oracle使用%rowtype变量存储一行数据
    Oracle使用%type类型的变量输出结果
    mdf与ldf文件如何还原到SQLserver数据库
  • 原文地址:https://www.cnblogs.com/zhao-xin/p/13156401.html
Copyright © 2011-2022 走看看