一、题目大意
- Codeup 1018
二、解题思路
- 简单的栈应用。
- 一种思路是先将中缀表达式转换为后缀表达式,然后再处理后缀表达式。
- 这里采用了直接计算的思路。设置一个操作数栈和一个操作符栈,读入当前数据,如果为操作数则压入数栈;为操作符则要与符栈顶的操作符比较优先级,如果优先级高则压入符栈;否则符栈弹出一个操作符,数栈弹出两个操作数进行计算,结果入栈,直到当前符栈顶的操作符的优先级低于要入栈的操作符的,然后操作符入栈。这样处理直至完成所有数据。
- 处理完所有数据后还要继续进行计算直至操作符栈空为止。
三、参考代码
#include<iostream>
#include<string>
#include<stack>
#include<map>
#include<cctype>
#include<iomanip>
using namespace std;
stack <char> op;
stack <double> od;
void cal() {
char x = op.top(); op.pop();
double n2 = od.top(); od.pop();
double n1 = od.top(); od.pop();
switch (x) {
case '+':od.push(n1 + n2); break;
case '-':od.push(n1 - n2); break;
case '*':od.push(n1 * n2); break;
case '/':od.push(n1 / n2); break;
}
}
int main() {
map <char, int> m;
string s;
m['+'] = 0, m['-'] = 0, m['*'] = 1, m['/'] = 1;
while (getline(cin, s) && s != "0") {
for (auto it = s.begin(); it != s.end(); it++)
if (*it == ' ') s.erase(it);
for (int i = 0; i < s.size(); i++) {
if (i < s.size() && isdigit(s[i])) {
int n1 = 0;
while (i < s.size() && isdigit(s[i]))
n1 = 10 * n1 + s[i++] - '0';
od.push(n1);
}
if (i < s.size() && !isdigit(s[i])) {
if (op.empty() || m[s[i]] > m[op.top()]) op.push(s[i]);
else{
while (op.size() && m[s[i]] <= m[op.top()]) cal();
op.push(s[i]);
}
}
}
while (op.size()) cal();
cout << fixed << setprecision(2) << od.top() << endl;
}
return 0;
}
四、解题感悟
- 如果有括号,则要设置左括号优先级最高,遇到右括号则要一直弹符栈,直到遇到左括号为止。其他是一样的处理办法。