数据结构之后缀表达式求值(java实现)

it2025-03-17  25

数据结构之后缀表达式求值(java实现)

前记

​ 今天在刷leet code的时候刷到了一道题,后缀表达式(逆波兰表达式)求值,我花了一会儿写了一下它的解法。但是今天我不谈什么是后缀表达式,有兴趣的同学可以去论坛上看看其他人聊后缀表达式的问题,单就解题来说,我用了最为常规的办法,应该也是初学者最容易理解的方法写的,故代码数量较多,一定要读下去哦!

图解分析

首先我们拿出一个后缀表达式的例子,这里我直接用力扣上的测试用例。

String[] expression = {"2", "1", "+", "3", "*"}; //其转化为中缀表达式就是 ((2 + 1) * 3) = 9

对于后缀表达式求值,我们有这样一个规则:

1. ==遇到数字则入栈。== 2. ==遇到算符则取出栈顶两个数字进行计算,并将结果压入栈中。==

我相信有很多同学会有疑惑为什么直接接给出了这个规则,怎么来的这个规则,其实我也会有这样的疑惑,但是我觉得有可能是因为计算机的工作原理,栈的工作原理所知,以前的程序员可能就总结出了很多规律供我们使用。实际上我们不用事事都去追根溯源,要学会使用工具和思考,该深思的地方才去深思,避免重复造轮子。

通过理解规则我们首先能想到的是,这个题我们应该要用到栈(Stack),所以我尝试用图的方式来演示该工作过程。

第一步:

{“2”, “1”, “+”, “3”, “*”}

首先遍历的是第一个元素 “2”,此时是数字,直接入栈。

第二步:

{“2”, “1”, “+”, “3”, “*”}

遍历下一个元素 “1” 依旧是数字,也是直接入栈。

第三步:

{“2”, “1”, “+”, “3”, “*”}

继续遍历下一个元素 “+”,此时我们遇到了规则里面的第二个条件,不是数字了,我们将从栈中弹出两个数字,进行运算,也就是==1 和 2==进行1+2=3,并将3入栈。

第四步:

{“2”, “1”, “+”, “3”, “*”}

遍历到第四个元素 “3”,直接入栈。

第五步:

{“2”, “1”, “+”, “3”, “*”}

遍历最后一个元素 “*”,此时又要从栈里面弹出两个数字,进行运算,也就是3*3=9,再将9入栈。

当遍历完链表中所有元素时,栈中的唯一的一个数字即为最终的运算结果。

接下来,我们准备进行代码实现。

代码实现

我们首先定义一个方法对弹出来的数字进行运算。

值得注意的是,在后缀表达式求值时,从栈中弹出来的数,越靠近栈底的数,就要作为被减数,被除数

代码如下:

/** * 该方法用于计算 */ public static int cal(int num1,int num2,String oper){ int result = 0; switch (oper){ case "+": result = num1 + num2; break; case "-": result = num2 - num1; //靠近栈底的做被减数 break; case "*": result = num1 * num2; break; case "/": result = num2 / num1; //靠近栈底的做被除数 break; default: break; } return result; }

然后还需要定义一个用于遍历字符数组,完成入栈弹栈操作的方法

代码如下:

public static int calculate(List<String> ls){ Stack<String> stack = new Stack<>(); for (String l : ls) { if (l.matches("-?\\d+")){//正则表达式匹配数字 stack.push(l); }else{ String num1 = stack.pop(); String num2 = stack.pop(); int calculate = cal(Integer.parseInt(num1), Integer.parseInt(num2), l); stack.push(String.valueOf(calculate)); } } return Integer.parseInt(stack.pop()); }

在对数字进行判别的时候我采用了正则表达式,并考虑到可能为多位数,负数的情况,不理解的同学可以去了解一下正则表达式。

最后就是测试了:

@Test public void test() { //定义一个逆波兰表达式 String[] surffixExpression = {"2", "1", "+", "3", "*"}; int result = calculate(surffixExpression); System.out.println(result); }
后记

至此,后缀表达式的求值就完成了,此方法我认为是初学者最容易理解的方法,不懂的同学可以多画图去理解,一边画图一边思考,算法题画图还是很重要的,动起来,一起学习。

最新回复(0)