输入:当一行中只有0 时输入结束,相应结果不输出。
分两步,一是将中缀转后缀,而是计算后缀表达式。
#include <iostream>
#include <cstdio>
#include <string>
#include <stack>
#include <queue>
#include <map>
using namespace std;
struct node {
double num; //操作数
char op; //操作符
bool flag; //true 表示操作数,false表示操作符
};
string str;
stack<node> s; //操作符栈
queue<node> q; //用队列存放后缀表达式序列
map<char, int> op; //用于判断操作符优先级
void Change() {
double num;
node temp;
for(int i = 0; i < str.length(); ) { //中缀转后缀
if(str[i] >= '0' && str[i] <= '9') { //如果是数字
temp.flag = true ;
temp.num = str[i++] - '0';
while(i < str.length() && str[i] >= '0' && str[i] <= '9') { //将操作数完整储存下来
temp.num = temp.num * 10 + (str[i] - '0');
++i;
}
q.push(temp); //操作数入队列
} else {
temp.flag = false; //是操作符
//理论上来说,操作符的优先级分栈内栈外,观察发现,除括号外
//操作符的栈内优先级均高于栈外优先级,而只有栈外优先级高于栈内时,入栈
//同时乘除的优先级显然高于加减,因此将其简化,不分栈内栈外优先级
//只要当前操作符栈顶的优先级低于当前操作符的优先级,就将栈顶出栈,入后缀表达式队列
//最后栈内的操作符优先级必然小于当前操作符,再将当前操作符入栈即可
while(!s.empty() && op[str[i]] <= op[s.top().op]) {
q.push(s.top()); //操作符栈顶元素入后缀表达式队列
s.pop(); //栈顶元素出栈
}
temp.op = str[i];
s.push(temp); //操作符入栈
++i;
}
}
//所有字符完成入栈,但是入队可能未完成
while(!s.empty()) { //将栈内剩下的操作符入后缀表达式队列
q.push(s.top());
s.pop();
}
}
double Cal() {
double temp1, temp2;
node cur, temp;
while(!q.empty()) {
//只要后缀表达式队列非空
cur = q.front(); //cur记录队列的队首元素
q.pop(); //队首元素出队
if(cur.flag == true) { //如果是操作数,将其入栈
s.push(cur) ; //栈s之前是放操作符的,但是整理出后续表达式序列后,就没用了,如今废物利用
} else { //如果会操作符
temp2 = s.top().num; //弹出第二操作数
s.pop();
temp1 = s.top().num; //弹出第一操作数
s.pop();
temp.flag = true;
if(cur.op == '+') {
temp.num = temp1 + temp2;
} else if(cur.op == '-'){
temp.num = temp1 - temp2;
} else if(cur.op == '*') {
temp.num = temp1 * temp2;
} else if(cur.op == '/') {
temp.num = temp1 / temp2;
}
s.push(temp); //结果入栈
}
}
return s.top().num; //栈顶为结果
}
int main() {
op['+'] = op['-'] = 1;
op['*'] = op['/'] = 2; //设置操作符优先级,
while(getline(cin, str), str != "0") {
for(string::iterator it = str.end(); it != str.begin(); --it) {
if(*it == ' ') { //去掉多余的空格
str.erase(it);
}
}
while(!s.empty()) {
s.pop(); //初始化栈,清空栈
}
Change();
printf("%.2lf", Cal());
}
return 0;
} ```