逆波兰表达式计算四则运算。请看题目要求:
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
然后想起了本科学的数据结构中有一部分讲到了这个逆波兰表达式,用比波兰表达式来计算的算法是典型的栈问题。将数字压入栈,遇到计算符的时候弹出运算数,进行运算,结果再压入栈。最后栈中的数据就是结果。先看答案,然后再对比之前学过的进行分析。
#include <iostream>
#include <vector>
#include <stack>
#include <string>
using namespace std;
class Solution {
public:
bool isOpeartor(string value){
// if(value == "+"||value == "-"||value == "*"||value == "/")
// return false;
// else
// return true;
bool val =true;
(value == "+")?(val=false):( (value == "-")?(val=false):((value == "*")?(val=false):( (value == "/")?(val=false):(val=true) )));
return val;
}
int calValue(int operator1,int operator2,string operators){
if(operators=="+")
return (operator1+operator2);
else if(operators=="-")
return (operator1-operator2);
else if(operators=="*")
return (operator1*operator2);
else
return (operator1/operator2);
}
int evalRPN(vector<string> &tokens) {
stack<int> str_stack;
vector<string>::iterator iter = tokens.begin();
while(iter != tokens.end()){
if(isOpeartor( (*iter))){
//true的话为数字
int tmp = atoi((*iter).c_str());
str_stack.push(tmp);
}
else{
int num2 = str_stack.top();
str_stack.pop();
int num1 = str_stack.top();
str_stack.pop();
str_stack.push(calValue(num1,num2,(*iter)));
}
iter++;
}
return str_stack.top();
}
};
第一遍的代码使用的是不是上述代码,区别在于isOpeartor方法使用的是注释部分,其运算的时间是:
基于第一题的解题习惯之后,惯性的就想了想有没有更优化更快速的方法,于是想着对代码进行优化。在仔细看了代码之后,发现最好优化的地方就是isOpeartor方法,于是将if else表达式换成?:这个三元运算符,运算的速度还是快于代码判断,结果时间果然快了近20ms:
暂时还没想到更好的地方优化,如果大家看到这篇博客,欢迎提出好的优化方法。
接下来分析这个问题与原来课本中的例子:
这个问题简化地方在于:拿到一个运算表达式不需要转化成逆波兰表达式,转化的过程其实难于这个运算过程,这个就简化了很多。第二个简化是这里没有更多其他的运算符,如一元运算符++等,如果包含了这些运算符就需要考虑运算符的优先级了。第三个简化是这里是通过vector存的表达式,如果改成string来存放表达式,这样的话难度就有提高了,需要自己去分析表达式。第三个简化是这里不支持浮点数计算。
任重道远啊。感觉还是太菜了,继续努力吧