<p>算术表达式求值问题通常有两种办法,一种是中缀表达式,另外一种是后缀表达式,即逆波兰式。这里实现逆波兰式求解。</p><p>第一步: 将数学表达式转换为逆波兰</p><p>使用栈和队列,栈保存操作符(+-×/), 队列保存操作数。</p><p>逐个从头扫描表达式字符串,</p><p>a) 如果是操作数,直接入队列</p><p>b) 如果是(,直接入栈</p><p>c) 如果是),弹出栈中操作符,直到遇见上一个(为止</p><p>d) 如果是操作符,加减乘除,则需要比较优先级,将栈顶优先级高于或等于当前操作符的一律弹出,压入队列</p><p>最后将stack 中所有操作符弹出,入队列。 返回队列中的结果
第二步: 计算逆波兰式表达式的值</p><span style="font-family: monospace; white-space: pre; background-color: rgb(240, 240, 240);">计算逆波兰式表达式的值相对简单,用一个stack保存中间结果,操作数直接push入stack,遇到操作数,pop out stack 中最后两个操作数,计算结果,将计算结果重新push 入stack。最后stack中栈顶元素即为最终结果</span>
class Solution {
public:
bool isOp(string op){
if(op.compare("+") == 0 ||
op.compare("-") == 0 ||
op.compare("*") == 0 ||
op.compare("/") == 0 ){
return true;
}
return false;
}
// greater: 1
// equal: 0
// less: -1
int compareOrder(string op1, string op2) {
int prio1 = 0, prio2 = 0;
if(op1.compare("*") == 0 ||
op1.compare("/") == 0){
prio1 = 1;
}
if(op2.compare("*") == 0 ||
op2.compare("/") == 0){
prio2 = 1;
}
return prio1 - prio2;
}
vector<string> convertToRPN(vector<string> &expression) {
vector<string> rpnList;
stack<string> opStack;
for(int i = 0; i < expression.size(); i++){
string now = expression[i];
if(now.compare("(") == 0){
opStack.push(now);
}
else if(now.compare(")") == 0){
while(opStack.top().compare("(") != 0){
rpnList.push_back(opStack.top());
opStack.pop();
}
opStack.pop();
}
else if(isOp(now)){
if(!opStack.empty() &&
isOp(opStack.top()) &&
compareOrder(opStack.top(), now) >= 0){
// pop out those ops with higher or equal order
rpnList.push_back(opStack.top());
opStack.pop();
}
opStack.push(now);
}
else {
rpnList.push_back(now);
}
}
while(!opStack.empty()) {
rpnList.push_back(opStack.top());
opStack.pop();
}
return rpnList;
}
int calculate(int a, int b, string op){
if(op.compare("+") == 0){
return a+b;
}
else if(op.compare("-") == 0){
return a-b;
}
else if(op.compare("*") == 0){
return a*b;
}
else if(op.compare("/") == 0){
return a/b;
}
return -1; // should never happen
}
int calculateRPN(vector<string> &expression) {
stack<int> s;
int number = 0;
for(int i = 0; i < expression.size(); i++){
string now = expression[i];
if(isOp(now)){
int b = s.top();
s.pop();
int a = s.top();
s.pop();
number = calculate(a, b, now);
s.push(number );
}
else {
number = stoi(now);
s.push(number);
}
}
return s.top();
}
/**
* @param expression: a vector of strings;
* @return: an integer
*/
int evaluateExpression(vector<string> &expression) {
// write your code here
if(expression.size() == 0){
return 0;
}
// 1. converted to reversed polish expression
vector<string> rpe = convertToRPN(expression);
// 2. caculate the reversed polish expression
return calculateRPN(rpe);
}
};