问题描述
Evaluate the value of an arithmetic expression in Reverse Polish Notation.
Valid operators are +, -, *, /
. Each operand may be an integer or another expression.
Some examples:
[“2”, “1”, “+”, “3”, ““] -> ((2 + 1) 3) -> 9
[“4”, “13”, “5”, “/”, “+”] -> (4 + (13 / 5)) -> 6
思路分析
实现逆波兰表示法。逆波兰表示法(Reverse Polish notation,RPN,或逆波兰记法),是一种是由波兰数学家扬·武卡谢维奇1920年引入的数学表达式方式,在逆波兰记法中,所有操作符置于操作数的后面,因此也被称为后缀表示法。逆波兰记法不需要括号来标识操作符的优先级。
使用栈来实现,如果string是数字就转化后入栈;如果是符号则将栈中两个元素出栈,先出栈的元素是被操作数,计算之后再次入栈。循环结束即可。
代码
class Solution {
public:
int evalRPN(vector<string>& tokens) {
if (tokens.size() == 0) return 0;
stack<int> stk;
int operand, a, b, res;
for (auto s : tokens){
if (!isOperator(s)){
operand = stoi(s);
stk.push(operand);
}
else{
b = stk.top();
stk.pop();
a = stk.top();
stk.pop();
res = cal(s, a, b);
stk.push(res);
}
}
return stk.top();
}
bool isOperator(string ch){
if (ch == "+" || ch == "-" || ch == "*" || ch == "/")
return true;
else
return false;
}
int cal(string ch, int a, int b){
int res = 0;
if (ch == "+"){
res = a + b;
return res;
}
else if (ch == "-"){
res = a - b;
return res;
}
else if (ch == "*"){
res = a * b;
return res;
}
else{
res = a / b;
return res;
}
}
};
时间复杂度:
未知
未
知
空间复杂度:
未知
未
知
反思
这里用的是stoi,这是写的最长的一个程序了(除了无脑的罗马数字转化)。
因为使用了栈,所以肯定可以用递归来实现的。这时使用&引用的优势体现出来了。我们就可以用tokens的末尾开始递归,每次递归提取出一个string。如果不是运算符则返回stoi后的数字;如果是计算符,则递归两步得到两个运算数进行计算。
class Solution {
public:
int evalRPN(vector<string>& tokens) {
string s = tokens.back();
tokens.pop_back();
if (s != "+" && s != "-" && s != "*" && s != "/")
return stoi(s);
int r2 = evalRPN(tokens);
int r1 = evalRPN(tokens);
if (s == "+") return r1 + r2;
if (s == "-") return r1 - r2;
if (s == "*") return r1 * r2;
if (s == "/") return r1 / r2;
}
};
让我写我是写不出来的,而且最后的终止条件也很巧妙,竟然在到达vector之后没有报错。