题目描述
中缀表达式的值http://stepbystep.openjudge.cn/stackqueue/10/
思路要点
- 输入字符串,而后解析得到操作符和操作数(用字符串数组存储)
- 利用操作符栈和操作数栈对表达式进行求解
代码
#include <iostream>
#include <string>
#include <vector>
#include <assert.h>
#include <stack>
#include <cstdlib>
using namespace std;
//把表达式分解为运算符和操作符的数组
void parseExprStr(string expr, vector<string>& expVct);
//打印运算符和操作符的数组
void printExpVct(vector<string>& expVct);
//求解表达式结果
int getResult(vector<string>& expVct);
int main()
{
int expNum;
cin >> expNum;
string line;
getline(cin, line);
for (int i = 0; i < expNum; i++)
{
getline(cin, line);
vector<string> expVct;
parseExprStr(line, expVct);
//printExpVct(expVct);
cout << getResult(expVct) << endl;
}
}
void parseExprStr(string expr, vector<string>& expVct)
{
assert(!expr.empty());
int i = 0;
while (i < expr.length())
{
if (isdigit(expr[i]))
{
string digitStr(1, expr[i]);
i++;
while (i < expr.length() && isdigit(expr[i]))
{
digitStr += expr[i];
i++;
}
expVct.push_back(digitStr);
}
else
{
expVct.push_back(string(1, expr[i]));
i++;
}
}
}
void printExpVct(vector<string>& expVct)
{
cout << "The expression is: ";
for (int i = 0; i < expVct.size(); i++)
cout << expVct[i] << " ";
cout << endl;
}
void handleCalculation(char opt, stack<int> &operands)
{
assert(operands.size() >= 2);
int right = operands.top();
operands.pop();
int left = operands.top();
operands.pop();
switch(opt)
{
case '+':
operands.push(left + right);
break;
case '-':
operands.push(left - right);
break;
case '*':
operands.push(left * right);
break;
case '/':
operands.push(left / right);
break;
}
}
int getLevel(char opt)
{
switch(opt)
{
case '(':
return 1;
case '+':
case '-':
return 2;
case '*':
case '/':
return 3;
}
}
//leftOp优先级高于或等于rightOp,则返回true,否则返回false
bool higherThan(char leftOpt, char rightOpt)
{
return getLevel(leftOpt) >= getLevel(rightOpt);
}
void handlePriorOperators(char opt, stack<int> &operands, stack<char>& opts)
{
while (!opts.empty() && higherThan(opts.top(), opt) )
{
handleCalculation(opts.top(), operands);
opts.pop();
}
return;
}
void handleOperator(char opt,stack<int> &operands, stack<char>& opts)
{
switch(opt)
{
case '(':
opts.push(opt);
break;
case ')':
while(!opts.empty() && opts.top() != '(')
{
handleCalculation(opts.top(), operands);
opts.pop();
}
if (!opts.empty())
opts.pop(); //'('
break;
case '+':
handlePriorOperators('+', operands, opts);
opts.push('+');
break;
case '-':
handlePriorOperators('+', operands, opts);
opts.push('-');
break;
case '*':
handlePriorOperators('*', operands, opts);
opts.push('*');
break;
case '/':
handlePriorOperators('/', operands, opts);
opts.push('/');
break;
}
}
int getResult(vector<string>& expVct)
{
stack<int> operands; //操作数栈
stack<char> opts; //操作符栈
for (int i = 0; i < expVct.size(); i++)
{
string op = expVct[i];
if (isdigit(op[0]))
{
operands.push(atoi(op.c_str()));
}
else
{
handleOperator(op[0], operands, opts);
}
}
while(!opts.empty())
{
handleCalculation(opts.top(), operands);
opts.pop();
}
assert(operands.size() == 1);
return operands.top();
}