题目:http://codeup.cn/problem.php?cid=100000605&pid=0

这道题一定要重点关注一下!!!看上去很简单的那种,还是有难度的

  1. 题目给出中缀表达式,求计算结果
  2. 这类表达式计算的题目,一般都是要转化为后缀表达式,然后在计算,所以这道题分两步走,先转后缀,再计算
  3. 由于一直是从左往右扫描,因此存储后缀表达式用queue
  4. 如果有(),那么碰到(就压入栈,碰到)就不停推出操作符栈,直到遇到(
  1. while(getline(cin, str), str != "0"){

代码

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<string>
  4. #include<map>
  5. #include<stack>
  6. #include<queue>
  7. using namespace std;
  8. struct node{
  9. double num;
  10. char op;
  11. bool flag;//true 表示操作数 false表示操作符
  12. };
  13. string str;
  14. stack<node> s;//操作符栈
  15. queue<node> q;//后缀表达式序列
  16. map<char, int> op;// 优先级映射
  17. void Change(){
  18. double num;
  19. node temp;
  20. for(int i = 0; i < str.length();){
  21. if(str[i] >= '0' && str[i] <= '9'){
  22. temp.flag = true;//此时是操作数
  23. temp.num = str[i++] - '0';//字符转数字
  24. while(i < str.length() && str[i] >= '0' && str[i] <= '9'){//当这个数字不止一位的时候
  25. temp.num = temp.num * 10 + str[i] - '0';
  26. i++;
  27. }
  28. q.push(temp);
  29. } else {//如果是运算符
  30. temp.flag = false;
  31. while(!s.empty() && op[str[i]] <= op[s.top().op]){//操作符栈栈顶节点的op符号
  32. q.push(s.top());
  33. s.pop();
  34. }
  35. temp.op = str[i];
  36. s.push(temp);
  37. i++;
  38. }
  39. }
  40. while(!s.empty()){
  41. q.push(s.top());
  42. s.pop();
  43. }
  44. }
  45. double Cal(){
  46. double temp1, temp2;
  47. node cur, temp;
  48. while (!q.empty()){
  49. cur = q.front();//cur是队首元素
  50. q.pop();
  51. if(cur.flag == true) s.push(cur);
  52. else{//队首是数字
  53. temp2 = s.top().num;//先弹出右边的操作数
  54. s.pop();
  55. temp1 = s.top().num;//后弹出的那个是左边的操作数
  56. s.pop();
  57. temp.flag = true;//临时记录操作数
  58. if(cur.op == '+') temp.num = temp1 + temp2;
  59. else if(cur.op == '-') temp.num = temp1 - temp2;
  60. else if(cur.op == '*') temp.num = temp1 * temp2;
  61. else if(cur.op == '/') temp.num = temp1 / temp2;
  62. s.push(temp);
  63. }
  64. }
  65. return s.top().num;//计算完毕
  66. }
  67. int main(){
  68. op['+'] = op['-'] = 1;
  69. op['*'] = op['/'] = 2;
  70. while(getline(cin, str), str != "0"){
  71. for(auto it = str.end(); it != str.begin(); it--){
  72. if(*it == ' ') str.erase(it);
  73. }
  74. while(!s.empty()) s.pop();
  75. Change();
  76. printf("%.2lf\n",Cal());
  77. }
  78. }