栈实现逆波兰计算器

逆波兰计算器

  1. 输入一个逆波兰表达式(后缀表达式),使用栈(Stack), 计算其结果
  2. 支持小括号和多位数整数只支持对整数的计算

思路分析

例如: (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,由此得出最终结果

package 栈;

import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

public class 逆波兰计算器 {
    public static void main(String[] args) {
        //先定义逆波兰表达式,为了分割字符串,数字和符号使用空格隔开
        String expression="30 4 + 5 * 6 -";
        //将表达式存放到集合中
        List<String> list = getListstring(expression);
        System.out.println("集合元素"+list);
        //调用方法得到计算结果
        int res = calculate(list);
        System.out.println("计算结果为"+res);

    }
    //将逆波兰表达式存放到集合中
    public static List<String> getListstring(String expression){
        //创建一个集合
        List<String> list=new ArrayList<String>();
        //将字符串按空格进行分割
        String[] split = expression.split(" ");
        //遍历字符串数组,依次添加到集合中
        for(String S:split){
            list.add(S);
        }
        return list;
    }

    //完成对逆波兰计算器的计算
    public static int calculate(List<String> list){
        //创建一个数栈,用来存放数
        Stack<String> sta=new  Stack<String>();
        //遍历集合,计算结果
        for(String item:list){
            //用正则表达式来取出数
            if(item.matches("\\d+")){//匹配的是多位数
                //如果是数字,则入栈
                sta.push(item);
            }
            else{//为符号,取出两个数和符号进行运算
                int num2=Integer.parseInt(sta.pop());
                int num1=Integer.parseInt(sta.pop());
                int res=0;
                if(item.equals("+")){
                    res=num1+num2;
                }
               else if(item.equals("-")){
                    res=num1-num2;
                }
                else if(item.equals("*")){
                    res=num1*num2;
                }
                else if(item.equals("/")){
                    res=num1/num2;
                }
                else{
                    throw new RuntimeException("运算符有误");
                }
                //将计算后的结果入栈
                sta.push(""+res);

            }
        }
        //最后留在栈中的数据就是运算结果
        return Integer.parseInt(sta.pop());
    }
}
    

**代码分析**

**主程序**
定义后缀表达式
借助集合,将表达式存入到集合中(集合元素[30, 4, +, 5, *, 6, -])
调用计算方法,计算出结果



**方法1:将表达式存入到集合中**

利用字符串的**expression.split方法**

  1、将字符串按空格分开给一个字符串数组

![](https://img2020.cnblogs.com/blog/2248084/202101/2248084-20210104182558410-1933146387.png)


此方法返回的数组包含此字符串的每个子字符串,由与给定表达式匹配的另一个子字符串终止,或由字符串的结尾终止。

2、遍历字符串数组,将字符串添加到集合中。



**方法2:将集合中的元素遍历计算结果**

1、遍历集合,如果为数字,直接入栈。判断条件:利用字符串的正则表达式**express.matches()**

![](https://img2020.cnblogs.com/blog/2248084/202101/2248084-20210104182627167-758548561.png)

正则表达式:详情参考:https://blog.csdn.net/victoryckl/article/details/6930409

告诉这个字符串是否匹配给定的[regular  expression](../util/regex/Pattern.html#sum) 

2、不为数字,从栈中pop出两个数计算,将计算结果入栈,pop出的两个数为字符型,需要调用方法

**注意:**

- pop出数的顺序。计算的表达式不相同。
- 计算的结果为INT型,入栈的为字符串型,利用小技巧 字符串拼接计算的结果sta.push(""+res);

**Integer.parseInt(String s)**

![](https://img2020.cnblogs.com/blog/2248084/202101/2248084-20210104182644636-587107748.png)


将字符串参数解析为带符号的十进制整数。  字符串中的字符都必须是十进制数字,除了第一个字符可能是ASCII减号`'-'` ( `'\u002D'`  )以指示负值或ASCII加号`'+'` ( `'\u002B'` )表示正值。

3、遍历完留在数栈中的数字就是计算结果。
posted @ 2021-01-04 18:27  胡木杨  阅读(175)  评论(0)    收藏  举报