逆波兰表达式

逆波兰表达式

逆波兰表示法

这里简单的说明一下什么是逆波兰表达式:

逆波兰(reverse Polish)表达式又叫后缀(postfix)表达式。

假设我们有一个便携式计算器并且想要计算一趟外出花费,那么我们可以列出一串计算式,比如:

这种是自然的输入方式: 5 * 3 + 6 + 7 * 3 =

这个结果最简单的四则运算计算器都能够计算出结果,随着计算器的不同,许多先进的计算器都知道乘除法优先于加减法,于是就出现了这种表达式

如果将上式改为后缀则为:5 3 * 6 + 7 3 * +

题目描述

根据逆波兰表示法,求表达式的值。

有效的算符包括 +、-、*、/。每个运算对象可以是整数,也可以是另一个逆波兰表达式。


题目分析

题目给定了一个String[] tokens字符串数组,所以对于数组中的数字(int)和元素符号(String)要进行是否是数字(是否是符号也行)的处理,这里可以使用一个isNumber(token)函数来处理,返回一个boolean类型,对于不同的符号,需要采用对应的运算,这里采用了switch(token),对四个符号四个分支,分别处理对应的运算

我的思路

有了对应判断符号和数字的方法,就可以定义一个栈,把数字放入栈中,使用循环,每次循环压栈一个数字,遇到字符,就弹出栈顶的元素两次,取出最后进入栈的两个数字,使用对应的符号进行运算,再把运算的结果进栈,再继续进行同样的操作

代码实现

个人习惯,对于能够用英文描述的变量也好,方法,类也好,只要能表示其意思,就不用再写注释了

这也就应验了,代码本身也可以作为注释

public int evalRPN(String[] tokens) {
    Stack<Integer> stack = new Stack<>();
    for (String token : tokens) {
        if (isNumber(token)) {
            stack.push(Integer.parseInt(token));
        } else {
            int secondNum = stack.pop();
            int firstNum = stack.pop();
            switch (token) {
                case "+":
                    stack.push(firstNum + secondNum);
                    break;
                case "-":
                    stack.push(firstNum - secondNum);
                    break;
                case "*":
                    stack.push(firstNum * secondNum);
                    break;
                case "/":
                    stack.push(firstNum / secondNum);
                    break;
                default:
            }
        }
    }
    return stack.pop();
}

public boolean isNumber(String token) {
    return !("+".equals(token) || "-".equals(token) || "*".equals(token) || "/".equals(token));
}

在else语句块的前两排是很容易出错的两排,

如果要处理上图中的结果,处理方式应该是1/2,第一次弹栈取出的是2,第二次弹出取出的是1,所以也就是说第一次取出的是除数,第二次取出的才是被除数,所以

int secondNum = stack.pop();
int firstNum = stack.pop(); 从命名也就解释了计算的方式

测试用例

public static void main(String[] args) {
    //String[] tokens = {"2","1","+","3","*"};
    String[] tokens = {"10","6","9","3","+","-11","*","/","*","17","+","5","+"};
    System.out.println("the result is:" + new EvalRPN().evalRPN(tokens));
}

posted @ 2021-05-09 18:11  先破防再敲  阅读(420)  评论(0)    收藏  举报