逆波兰表达式求值
来源:力扣(LeetCode)
题目链接:https://leetcode-cn.com/problems/evaluate-reverse-polish-notation
Problem Description
根据 逆波兰表示法,求表达式的值。
难度:中等
有效的算符包括 +、-、*、/ 。每个运算对象可以是整数,也可以是另一个逆波兰表达式。
说明:
- 整数除法只保留整数部分。
- 给定逆波兰表达式总是有效的。换句话说,表达式总会得出有效数值且不存在除数为 0 的情况。
Sample1
输入:tokens = ["2","1","+","3","*"]
输出:9
解释:该算式转化为常见的中缀算术表达式为:((2 + 1) * 3) = 9
Sample2
输入:tokens = ["4","13","5","/","+"]
输出:6
解释:该算式转化为常见的中缀算术表达式为:(4 + (13 / 5)) = 6
Sample3
输入:tokens = ["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
Hint
1 <= tokens.length <= 1 0 4 10^4 104
tokens[i] 要么是一个算符("+"、"-"、"*" 或 “/”),要么是一个在范围 [-200, 200] 内的整数
Solution
首先我们要知道逆波兰表达式到底是什么,逆波兰表达式是一种后缀表达式,所谓后缀就是指算符写在后面。
比如我们平常使用的表达式都是中缀表达式,形如( 1 + 2 ) * ( 3 + 4 ),而该表达式对应的后缀表达式为( ( 1 2 + ) ( 3 4 + ) * ),相信学习过数据结构的小伙伴都知道如何计算对后缀表达式求值。
既然是学习算法,那我们就考虑逆波兰表达式求值问题,如何用程序更好地进行求解!
解决策略
1.首先需要编写一个将字符串转化成数值的函数,我们将此函数命名convert函数,其中需要注意的是: 将负数字符串转化为数值时,应该注意负号的处理。
2. 逆波兰式特别适合用栈这种数据结构求值,遇到数字则入栈;遇到算符则取出栈顶两个数字进行计算,并将结果压入栈中。有一点需要注意的是:在进行减法(或者除法操作)时,需要弄清楚减数和被减数是谁(除数和被除数是谁)。遇到减号时,栈顶元素是减数,栈顶元素弹出后的新栈顶元素是被减数。
3. 最后,栈中比如只剩下一个元素,这个元素就是答案。
当真正理解了栈的结构,这题就迎刃而解啦。这题的思路可以参考下图理解。
Code
class Solution {
public:
int evalRPN(vector<string>& tokens) {
int len= tokens.size();
stack<int>st;
int res=0;
int a,b,type;
for(int i=0;i<len;i++)
{
type=oper(tokens[i]); //判断符号的类型,是数字,还是运算符?
if(type==0)
{
st.push(convert(tokens[i]));
}
else if(type==1)
{
a=st.top(); //取出栈顶元素
st.pop();
b=st.top();
st.pop();
res=a+b;
st.push(res);
}
else if(type==2)
{
a=st.top();
st.pop();
b=st.top();
st.pop();
res=b-a;
st.push(res);
}
else if(type==3)
{
a=st.top();
st.pop();
b=st.top();
st.pop();
res=a*b;
st.push(res);
}
else if(type==4)
{
a=st.top();
st.pop();
b=st.top();
st.pop();
res=b/a;
st.push(res);
}
}
return st.top();
}
int oper(string s) //判断符号类型
{
if(s=="+")
return 1;
else if(s=="-")
return 2;
else if(s=="*")
return 3;
else if(s=="/")
return 4;
else return 0;
}
int convert(string s) //将String类型的数字转化为int类型
{
int res=0;
int len=s.length();
if(s[0]!='-')
{
for(int i=0;i<len;i++)
{
res=res*10+(s[i]-'0');
}
}
else
{
for(int i=1;i<len;i++) //如果为负数,则从s[1]开始计算
{
res=res*10+(s[i]-'0');
}
res*=-1;
}
return res;
}
};
/*
*
* ┏┓ ┏┓+ +
* ┏┛┻━━━┛┻┓ + +
* ┃ ┃
* ┃ ━ ┃ ++ + + +
* ████━████+
* ◥██◤ ◥██◤ +
* ┃ ┻ ┃
* ┃ ┃ + +
* ┗━┓ ┏━┛
* ┃ ┃ + + + +Code is far away from
* ┃ ┃ + bug with the animal protecting
* ┃ ┗━━━┓ 神兽保佑,代码无bug
* ┃ ┣┓
* ┃ ┏┛
* ┗┓┓┏━┳┓┏┛ + + + +
* ┃┫┫ ┃┫┫
* ┗┻┛ ┗┻┛+ + + +
*/
最后感谢小伙伴们的学习噢~