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

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

前记

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

图解分析

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

String[] expression = {"2", "1", "+", "3", "*"};

//其转化为中缀表达式就是 ((2 + 1) * 3) = 9

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

1. ==遇到数字则入栈。==

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

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

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

第一步:

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

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

4c809ee727fe559e043c2909e1d8f934.png

第二步:

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

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

76ca9e536bfb71f7fbddf7a98cd82d98.png

第三步:

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

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

25add15bed1ddb13656d828b521b3611.png

第四步:

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

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

819b6f8e89227a96febda3851403ceda.png

第五步:

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

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

a15b41d4a79eb5ab36391ae789e8cec7.png

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

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

代码实现

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

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

代码如下:

/**

* 该方法用于计算

*/

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){

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);

}

后记

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值