逆波兰表达式求值 java_LeetCode 150:逆波兰表达式求值 Evaluate Reverse Polish Notation...

题目:

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

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

Evaluate the value of an arithmetic expression in Reverse Polish Notation.

Valid operators are +, -, *, /. Each operand may be an integer or another expression.

说明:

整数除法只保留整数部分。

给定逆波兰表达式总是有效的。换句话说,表达式总会得出有效数值且不存在除数为 0 的情况。

Note:

Division between two integers should truncate toward zero.

The given RPN expression is always valid. That means the expression would always evaluate to a result and there won’t be any divide by zero operation.

示例 1:

输入: ["2", "1", "+", "3", "*"]

输出: 9

解释: ((2 + 1) * 3) = 9

示例 2:

输入: ["4", "13", "5", "/", "+"]

输出: 6

解释: (4 + (13 / 5)) = 6

示例 3:

输入: ["10", "6", "9", "3", "+", "-11", "*", "/", "*", "17", "+", "5", "+"]

输出: 22

解释:

((10 * (6 / ((9 + 3) * -11))) + 17) + 5

= ((10 * (6 / (12 * -11))) + 17) + 5

= ((10 * (6 / -132)) + 17) + 5

= ((10 * 0) + 17) + 5

= (0 + 17) + 5

= 17 + 5

= 22

扩展:

逆波兰表达式,它的语法规定,表达式必须以逆波兰表达式的方式给出。逆波兰表达式又叫做后缀表达式。这个知识点在数据结构和编译原理这两门课程中都有介绍,下面是一些例子:

a+b ---> a,b,+

a+(b-c) ---> a,b,c,-,+

a+(b-c)*d ---> a,b,c,-,d,*,+

a+d*(b-c)--->a,d,b,c,-,*,+

a=1+3 ---> a,1,3,+,=

从上面的例子可以看出:

(1) 在两种表示中,运算对象出现的顺序相同;

(2) 在后缀表示中,运算符按实际计算顺序从左到右排列,且每一运算符总是跟在其运算对象之后。

这种表达式很反人类,但是对计算机很友好,因为计算机运算是利用栈数据结构。

解题思路:

可以看出逆波兰表达式中的每一个运算符属于该运算符前的两个数字间的运算。如:

如波兰表达式:1,2,+

则加号前两个数字为1,2。其运算符就是加号:1+2

得出结果:1+2=3

如波兰表达式:1,2,3,+,-

则加号前两个数字为2,3。其运算符就是加号:2+3

得出结果2+3=5,则波兰表达式变为:1,5,-

减号前两个数字为1,5,其运算符就是减号:1-5

得出结果1-5=-4

由上面的的例子思路就很清晰了,直接用指针遍历表达式,遇到数字就入栈,遇到运算符就弹出两个数字,把他们运算之后得出结果,再作为独立数字入栈。最后栈内只剩一个元素 即表达式运算结果。也可以用递归

Java:

class Solution {

public int evalRPN(String[] tokens) {

Stack stack = new Stack<>();

for (String t : tokens) {

if (t.equals("+")) {

stack.push(stack.pop() + stack.pop());

} else if (t.equals("-")) {

int tmp = stack.pop();

stack.push(stack.pop() - tmp);

} else if (t.equals("*")) {

int tmp = stack.pop();

stack.push(stack.pop() * tmp);

} else if (t.equals("/")) {

int tmp = stack.pop();

stack.push(stack.pop() / tmp);

} else {

stack.push(Integer.parseInt(t));

}

}

return stack.pop();

}

}

Python:

python也可以用数组代替栈完成上述方法解答本题。这里用另一个函数 eval() 代替上述四个 if 判断:

class Solution:

def evalRPN(self, tokens: List[str]) -> int:

stack = []

for t in tokens:

if t in '+-*/':

tmp = stack.pop()

stack.append(int(eval('stack.pop()' + t + 'tmp')))

else:

stack.append(int(t))

return stack.pop()

eval() 函数可以执行传入参数 字符串语句。

如 eval('print("hhhhh")') 会执行参数字符串打印出: hhhhh

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
KMP算法是一种字符串匹配算法,用于在一个文本串S内查找一个模式串P的出现位置。它的时间复杂度为O(n+m),其中n为文本串的长度,m为模式串的长度。 KMP算法的核心思想是利用已知信息来避免不必要的字符比较。具体来说,它维护一个next数组,其中next[i]表示当第i个字符匹配失败时,下一次匹配应该从模式串的第next[i]个字符开始。 我们可以通过一个简单的例子来理解KMP算法的思想。假设文本串为S="ababababca",模式串为P="abababca",我们想要在S中查找P的出现位置。 首先,我们可以将P的每个前缀和后缀进行比较,得到next数组: | i | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | | --- | - | - | - | - | - | - | - | - | | P | a | b | a | b | a | b | c | a | | next| 0 | 0 | 1 | 2 | 3 | 4 | 0 | 1 | 接下来,我们从S的第一个字符开始匹配P。当S的第七个字符和P的第七个字符匹配失败时,我们可以利用next[6]=4,将P向右移动4个字符,使得P的第五个字符与S的第七个字符对齐。此时,我们可以发现P的前五个字符和S的前五个字符已经匹配成功了。因此,我们可以继续从S的第六个字符开始匹配P。 当S的第十个字符和P的第八个字符匹配失败时,我们可以利用next[7]=1,将P向右移动一个字符,使得P的第一个字符和S的第十个字符对齐。此时,我们可以发现P的前一个字符和S的第十个字符已经匹配成功了。因此,我们可以继续从S的第十一个字符开始匹配P。 最终,我们可以发现P出现在S的第二个位置。 下面是KMP算法的C++代码实现:

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值