一、问题描述
根据 逆波兰表示法,求表达式的值。有效的运算符包括 +, -, *, / 。每个运算对象可以是整数,也可以是另一个逆波兰表达式。
说明:整数除法只保留整数部分;给定逆波兰表达式总是有效的。换句话说,表达式总会得出有效数值且不存在除数为 0 的情况。
示例 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
逆波兰表达式:逆波兰表达式是一种后缀表达式,所谓后缀就是指算符写在后面。平常使用的算式则是一种中缀表达式,如 ( 1 + 2 ) * ( 3 + 4 ) 。该算式的逆波兰表达式写法为 ( ( 1 2 + ) ( 3 4 + ) * ) 。
逆波兰表达式主要有以下两个优点:①去掉括号后表达式无歧义,上式即便写成 1 2 + 3 4 + * 也可以依据次序计算出正确结果。②适合用栈操作运算:遇到数字则入栈;遇到算符则取出栈顶两个数字进行计算,并将结果压入栈中。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/evaluate-reverse-polish-notation
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
二、解题思路
构建一个栈(能够进行数据的插入、删除、获取栈顶元素即可),遍历所给字符串数组,只有当字符串表达的是一个运算符时就从栈中读取两个字符串进行相应的加、减、乘、除运算,并将运算结果在入栈,其他字符串直接入栈。
注意:①将两个字符串进行运算时需要将字符串转成整数进行运算,同样将运算结果入栈时也要将结果转为string类型入栈。在进行转换时,需要注意的是负数的转换。②由于题目所给表达式总是有效,我们不需要考虑栈空等特殊情况。③字符串数组遍历完,栈中的元素就是运算结果的字符串形式。
栈
class Stack{
public:
//入栈
void StackPush(string x){
_a.push_back(x);
}
//出栈
void StackPop(){
_a.pop_back();
}
//判断栈空
bool StackEmpty(){
return !(_a.size());
}
//获取栈顶元素
string& StackTop(){
return _a.back();
}
private:
vector<string> _a;
};
string转整数
//将字符串转为整数
int StringToInt(string& str){
string::iterator it = str.begin();
int flag = 1;
if(*it == '-'){
flag = -1;
it++;
}
int ret = 0;
while(it < str.end()){
ret = ret*10 + (*it - '0');
it++;
}
return ret*flag;
}
整数转string
//将整数转成字符串
string IntToString(int num){
string str;
int num1 = num;
if(num < 0)
num1 = -num;
while(num1){
str.push_back(num1%10+'0');
num1/=10;
}
if(num < 0)
str.push_back('-');
Inverted(str);
return str;
}
三、代码描述
class Stack{
public:
//入栈
void StackPush(string x){
_a.push_back(x);
}
//出栈
void StackPop(){
_a.pop_back();
}
//判断栈空
bool StackEmpty(){
return !(_a.size());
}
//获取栈顶元素
string& StackTop(){
return _a.back();
}
private:
vector<string> _a;
};
class Solution {
public:
//逆置字符串
void Inverted(string& str){
string::iterator b = str.begin();
string::iterator e = str.end()-1;
while(b < e){
char ch = *b;
*b = *e;
*e = ch;
b++;
e--;
}
}
//将字符串转为整数
int StringToInt(string& str){
string::iterator it = str.begin();
int flag = 1;
if(*it == '-'){
flag = -1;
it++;
}
int ret = 0;
while(it < str.end()){
ret = ret*10 + (*it - '0');
it++;
}
return ret*flag;
}
//将整数转成字符串
string IntToString(int num){
string str;
int num1 = num;
if(num < 0)
num1 = -num;
while(num1){
str.push_back(num1%10+'0');
num1/=10;
}
if(num < 0)
str.push_back('-');
Inverted(str);
return str;
}
int evalRPN(vector<string>& tokens) {
Stack st;
//遍历vector
for(int i = 0;i < tokens.size();i++){
//如果为运算符,就从栈中取两个元素进行元素
if(tokens[i].compare("+") == 0 || tokens[i].compare("-") == 0 || tokens[i].compare("*") == 0 || tokens[i].compare("/") == 0){
//获取栈顶元素并转为整数
int num1 = StringToInt(st.StackTop());
//栈顶元素出栈
st.StackPop();
int num2 = StringToInt(st.StackTop());
st.StackPop();
//将num1 num2的结果转为string并入栈
if(tokens[i].compare("+") == 0){
st.StackPush(IntToString(num1+num2));
}else if(tokens[i].compare("-") == 0){
st.StackPush(IntToString(num2-num1));
}else if(tokens[i].compare("*") == 0){
st.StackPush(IntToString(num1*num2));
}else{
st.StackPush(IntToString(num2/num1));
}
}
//不是运算符就进行入栈
else
st.StackPush(tokens[i]);
}
return StringToInt(st.StackTop());
}
};