• 栈实现逆波兰计算器(后缀表达式)


    逆波兰计算器

      设计一个逆波兰计算器,可以完成如下任务:

       (1)输入一个逆波兰表达式(后缀表达式),使用栈(stack),计算其结果。

       (2)支持小括号和多位数整数。

       (3)思路分析

          从左至右扫描表达式,遇到数字时,将数字压入堆栈,遇到运算符时,弹出栈顶的两个数,用运算符对它们做相应的计算(次顶元素 和 栈顶元素),并将结果入栈;重复上述过程直到表达式最右端,最后运算得出的值即为表达式的结果。

          Demo:

    例如: (3+4)×5-6 对应的后缀表达式就是 3 4 + 5 × 6 - , 针对后缀表达式求值步骤如下:
    
    (1)从左至右扫描,将3和4压入堆栈;
    (2)遇到+运算符,因此弹出4和3(4为栈顶元素,3为次顶元素),计算出3+4的值,得7,再将7入栈;
    (3)将5入栈;
    (4)接下来是×运算符,因此弹出5和7,计算出7×5=35,将35入栈;
    (5)将6入栈;
    (6)最后是-运算符,计算出35-6的值,即29,由此得出最终结果   

       (4)代码实现

     1 import java.util.ArrayList;
     2 import java.util.List;
     3 import java.util.Stack;
     4 
     5 public class PolandNotation {
     6 
     7     public static void main(String[] args) {
     8         // 先定义一个逆波兰表达式
     9         // (3+4)*5-6 => 3 4 + 5 *6 - = 29
    10         // 为了方便,数字和符号使用空格间隔
    11         String suffixExpression = "3 4 + 5 * 6 -";
    12 
    13         // 思路
    14         // 1.先将表达式放入 ArrayList 中
    15         // 2.将 ArrayList 传递给一个方法,遍历 Arraylist,配合栈,完成计算
    16 
    17         List<String> list = getListString(suffixExpression);
    18         System.out.println("List=" + list);
    19 
    20         int res = calculate(list);
    21         System.out.println("计算的结果是=" + res);
    22     }
    23 
    24     // 将一个逆波兰表达式,依次将数据和运算符放入到 ArrayList中
    25     public static List<String> getListString(String suffixExpression) {
    26         // 将 表达式分割
    27         String[] split = suffixExpression.split(" ");
    28         List<String> list = new ArrayList<String>();
    29         for (String ele : split) {
    30             list.add(ele);
    31         }
    32         return list;
    33     }
    34 
    35     // 完成对逆波兰表达式的计算
    36     /*
    37      * 1)从左至右扫描,将3和4压入堆栈 
    38      * 2)遇到+运算符,因此弹出4和3(4为栈顶元素,3为次顶元素),计算出3+4的值,得7,再将7入栈; 
    39      * 3)将5入栈;
    40      * 4)接下来是×运算符,因此弹出5和7,计算出7×5=35,将35入栈; 
    41      * 5)将6入栈; 
    42      * 6)最后是-运算符,计算出35-6的值,即29,由此得出最终结果
    43      */
    44 
    45     public static int calculate(List<String> ls) {
    46         // 创建一个栈,只需要一个栈
    47         Stack<String> stack = new Stack<String>();
    48         // 遍历 ls
    49         for (String item : ls) {
    50             // 使用正则表达式来取出数
    51             if (item.matches("\d+")) { // 匹配的是多位数
    52                 // 入栈
    53                 stack.push(item);
    54             } else {
    55                 // pop出两个数并运算,再入栈
    56                 int num2 = Integer.parseInt(stack.pop());
    57                 int num1 = Integer.parseInt(stack.pop());
    58                 int res = 0;
    59                 if (item.equals("+")) {
    60                     res = num2 + num1;
    61                 } else if (item.equals("-")) {
    62                     res = num1 - num2;
    63                 } else if (item.equals("*")) {
    64                     res = num2 * num1;
    65                 } else if (item.equals("/")) {
    66                     res = num1 / num2;
    67                 } else {
    68                     throw new RuntimeException("运算符有误");
    69                 }
    70 
    71                 // res 入栈
    72                 stack.push(res + "");
    73             }
    74         }
    75         // 最后留在stack中的数据就是运算结果
    76         return Integer.parseInt(stack.pop());
    77     }
    78 
    79 }
  • 相关阅读:
    【CF536D】Tavas in Kansas(博弈+动态规划)
    【CF643F】Bears and Juice(信息与可区分情况数)
    【AT3981】[ARC093D] Dark Horse(容斥+状压DP)
    【CF708E】Student's Camp(动态规划)
    【洛谷6775】[NOI2020] 制作菜品(思维好题)
    【洛谷2282】[HNOI2003] 历史年份(线段树优化DP)
    【洛谷5068】[Ynoi2015] 我回来了(线段树)
    【洛谷4117】[Ynoi2018] 五彩斑斓的世界(第二分块)
    【洛谷3745】[六省联考2017] 期末考试(水题)
    【AtCoder】AtCoder Grand Contest 050 解题报告(A~D)
  • 原文地址:https://www.cnblogs.com/niujifei/p/11595773.html
Copyright © 2020-2023  润新知