题目:http://codeup.cn/problem.php?cid=100000605&pid=0
这道题一定要重点关注一下!!!看上去很简单的那种,还是有难度的
- 题目给出中缀表达式,求计算结果
- 这类表达式计算的题目,一般都是要转化为后缀表达式,然后在计算,所以这道题分两步走,先转后缀,再计算
- 由于一直是从左往右扫描,因此存储后缀表达式用queue
- 如果有(),那么碰到(就压入栈,碰到)就不停推出操作符栈,直到遇到(
while(getline(cin, str), str != "0"){
代码
#include<iostream>#include<cstdio>#include<string>#include<map>#include<stack>#include<queue>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]){//操作符栈栈顶节点的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);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(auto it = str.end(); it != str.begin(); it--){if(*it == ' ') str.erase(it);}while(!s.empty()) s.pop();Change();printf("%.2lf\n",Cal());}}
