逆波兰表达式求值(栈方法)

力扣oj链接:https://leetcode.cn/problems/evaluate-reverse-polish-notation/

一、逆波兰表示法

百科解释:逆波兰表示法(Reverse Polish notation,RPN,或逆波兰记法),是一种是由波兰数学家扬·武卡谢维奇1920年引入的数学表达式方式,在逆波兰记法中,所有操作符置于操作数的后面,因此也被称为后缀表示法。

中缀表达式:就是我们平时用的表达式,比如 1+((2+3)*4)-5这种表达式

后缀表达式(逆波兰式):就是通过逆波兰表示法将中缀表达式进行转换,将所有操作符置于操作数的后面,操作数就是数字,操作符就是+、-、*、/这一类运算符

比如:“1+((2+3)*4)-5”转换为后缀表达式是”1 2 3 + 4 * + 5 -”,可以发现后缀表达式里没有括号。

具体可以用这样的方法转换

这里我们先把中缀表达式写为这样:1+2 + 3*4-5在表达式里每一步运算都加上括号,颜色相同的括号相对应,然后我们将对应的操作符(运算符)挪到对应的括号后面,如下:

12 3)+4)*)+5)-

然后我们去掉括号就得到了后缀表达式:1 2 3 + 4 * + 5 -

二、解题思路

这个题目题意,就是将后缀表达式放进数组里,然后对这个数组进行遍历,然后一个一个的放进栈中运行,具体思路如下:

首先将表达式中的数字依次放入栈中,逢操作符就停止入栈,然后将栈顶的数字作为遇到的操作符

右边的操作数,栈顶下的数字作为操作符左边的操作数,因为操作符的不同左右不可颠倒,出栈以后对出栈后形成的表达式进行运算后,将此结果入栈,然后将原表达式继续入栈。同理进行,最后结果应为16。

图示如下:

具体代码编写如下:

1.首先我们定义一个evalRPN()方法,参数为tokens数组,数组中存放你想要输入的后缀表达式,如题https://leetcode.cn/problems/evaluate-reverse-polish-notation/中所示,然后定义一个栈:

 public  int evalRPN(String[] tokens) {
       Stack<Integer> stack = new Stack<>(); //先定义一个栈
}

2.然后我们需要遍历这个数组,将数组元素放入到栈中

 public  int evalRPN(String[] tokens) {
       Stack<Integer> stack = new Stack<>(); //先定义一个栈
         for (String x: tokens) { //使用foreach遍历

        }
}

在遍历数组过程中,我们需要判断遍历的元素是否为操作符,因为操作符不放入栈中,所以我们需要定义一个方法,判断遍历的元素是不是操作符:

//判断evalRPN()方法中,foreach遍历的元素是不是运算符
    private boolean isOperation(String x) {
        if(x.equals("+") || x.equals("-") || x.equals("*") || x.equals("/")) {
            return true;
        }
        return false;
    }

3.根据遍历进栈时是否为位操作符确定条件

 public  int evalRPN(String[] tokens) {
       Stack<Integer> stack = new Stack<>(); //先定义一个栈
        for (String x: tokens) { //遍历输入的数组(由后缀表达式组成)
            if (!isOperation(x)) {//如果不是操作符,直接入栈
                stack.push(Integer.parseInt(x));//因为x是string类型,不能push到栈中没所以需要转换
            } else {//如果不是操作符
                //定义遍历进栈时遇到操作符后出栈的操作数num2,num1,num2为操作符右边的操作数
                int num2 = stack.pop();
                int num1 = stack.pop();
                switch (x) { //根据操作符的不同去定义后续入栈的几种可能
                    case "+" :
                        stack.push(num1+num2);
                        break;
                    case "-" :
                        stack.push(num1-num2);
                        break;
                    case "*" :
                        stack.push(num1*num2);
                        break;
                    case "/" :
                        stack.push(num1/num2);
                        break;
                }
            }
        }
        return stack.pop();
       
    }

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值