【STL之栈的应用】HDU-1237 简单计算器
注解
1、核心考点:栈的使用。首先将操作数和操作符分开,遇到操作数就放入操作数栈,如果遇到操作符,要看当前操作符与栈顶操作符的优先级大小。如果当前操作符栈不空,并且当前操作符比栈顶操作符优先级低,则应该先去把栈顶操作符的运算处理了。反之,如果操作符栈为空,或者当前操作符比栈顶操作符优先级高或相等,则把当前操作符压入栈中。
2、处理运算的过程:从操作数栈的栈顶取两个操作数,并从操作符栈的栈顶取一个操作符,进行运算。需要注意,运算结果精确到小数点两位,因此运算过程要用double类型,需要写一个string->double的函数,一般用stringstream即可。
3、注意处理最后一个运算时与处理之前的运算的区别:当处理最后一个运算时,不需要再把运算符压入栈中了。而处理非最后一个运算时,处理结束后需要把当前运算符压入运算符栈中。
4、不同优先级的运算符,可以用map的形式保存。
代码
#include <iostream>
#include <stack>
#include <map>
#include <sstream>
using namespace std;
map<char, int> mp;
stack<double> num;
stack<char> ope;
double strToDou(string s) {
stringstream ss;
ss<<s;
double n;
ss>>n;
return n;
}
void process(char tmp) {
while(!ope.empty() && mp[ope.top()]>=mp[tmp]) {
double a2 = num.top();
num.pop();
double a1 = num.top();
num.pop();
char op = ope.top();
ope.pop();
double ans = 0;
if(op=='+') {
ans = a1+a2;
}
if(op=='-') {
ans = a1-a2;
}
if(op=='*') {
ans = a1*a2;
}
if(op=='/') {
ans = a1/a2;
}
num.push(ans);
}
if(tmp!='!') {
ope.push(tmp);
}
}
int main() {
mp['+'] = 1;
mp['-'] = 1;
mp['*'] = 2;
mp['/'] = 2;
string s;
getline(cin, s);
while(s.compare("0")) {
//初始化,清空操作数栈和运算符栈
while(!num.empty()) {
num.pop();
}
while(!ope.empty()) {
ope.pop();
}
//遍历输入字符串
while(s.find(" ")!=-1) {
string tmp = s.substr(0, s.find(" "));
s = s.substr(s.find(" ")+1);
if(tmp.at(0)=='+' || tmp.at(0)=='-' || tmp.at(0)=='*' || tmp.at(0)=='/') {
if(ope.empty() || mp[ope.top()]<mp[tmp.at(0)]) {
ope.push(tmp.at(0));
} else {
process(tmp.at(0));
}
} else {
double n = strToDou(tmp);
num.push(n);
}
}
//把最后一个运算数放入栈中
double last = strToDou(s);
num.push(last);
//处理最后一个表达式直到结束
if(ope.size()) {
process('!');
}
printf("%.2lf\n", num.top());
getline(cin, s);
}
return 0;
}