力扣第150题-逆波兰表达式求值

423 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第17天,点击查看活动详情

前言

力扣第150题 逆波兰表达式求值 如下所示:

image.png

一、思路

毫无疑问现需要了解清楚什么是 逆波兰表示法

逆波兰表示法

逆波兰表示法 是一种 后缀表示式,也就是说运算符会写在数字的后面。以示例一中的作为例子:

  • 常见的中缀表达式:((2 + 1) * 3)
  • 后缀表示式(逆波兰表示法):((2 1 +) 3 *)

那后缀表示式有什么用呢?后缀表达式可以消除 括号 对与计算结果的影响,也就是说 ((2 1 +) 3 *)2 1 + 3 * 是一样的

在了解了 逆波兰表示法 后,很明显可以发现运算符号只处理他之前的元素或者运算后的结果,如下图所示:

下图中的加号就是处理 2 + 1

image.png

下图中的称号是处理子式子的结果 3 * 3

image.png

经过上面的分析,我们不难发现这一题可以使用 来存储需要计算值和计算后的结果,因为运算符始终都是取前面的两个值。大致的步骤人如下所示:

遍历表达式,会出现以下两种情况:

  • 数字:直接入栈,用于之后的计算
  • 预算符号:从栈中取出两个元素并按照运算符计算,再将计算后的结果入栈

二、实现

实现代码

需要注意的是,栈顶的元素是运算符计算的第二个元素!

实现的代码如下所示:

public int evalRPN(String[] tokens) {
    Stack<Integer> numStack = new Stack<>();
    //
    for (String str : tokens){
        if (isSign(str)){
            // 出栈两个元素
            Integer n2 = numStack.pop();
            Integer n1 = numStack.pop();
            int ret = calc(n1, n2, str);
            numStack.push(ret);
        } else {
            // 碰到数字就入栈
            numStack.push(Integer.valueOf(str));
        }
    }
    return numStack.pop();
}

private boolean isSign(String str){
    return "+".equals(str) || "-".equals(str) || "*".equals(str) || "/".equals(str);
}

/**、
 * n1是前面的一个元素
 */
private int calc(Integer n1, Integer n2, String str){
    int ret = 0;
    if ("+".equals(str)){
        ret = n1 + n2;
    } else if ("-".equals(str)){
        ret = n1 - n2;
    } else if ("*".equals(str)){
        ret = n1 * n2;
    } else {
        ret = n1 / n2;
    }
    return ret;
}

测试代码

public static void main(String[] args) {
    String[] strings = {"2","1","+","3","*"};
    new Number150().evalRPN(strings);
}

结果

image.png

三、总结

今天一次就过了,甚至没有写一个测试用例。

感谢看到最后,非常荣幸能够帮助到你~♥

如果你觉得我写的还不错的话,不妨给我点个赞吧!如有疑问,也可评论区见~