当前位置:   article > 正文

【程序填空】表达式计算(栈应用)_optr.push('#');

optr.push('#');

 

题目描述

使用C++自带的stack栈模板来实现四则运算表达式求值

算法描述参考第3.2.5节

算法伪代码参考P53-54的算法3.4

例如

1. Push (OPTR, '#');表示把字符#压入堆栈OPTR中,转换成c++代码就是OPTR.push('#');

2. Pop(OPND, a); 表示弹出栈OPND的栈顶元素,并把栈顶元素放入变量a中。因此改成c++代码是两个操作:a = OPND.top();   OPND.pop();

3. a = GetTop(OPND)表示获取栈OPND的栈顶元素,转成c++代码就是: a = OPND.top();

大家主要是改造表达式求值函数EvaluateExpression的代码

输入

第一个输入t,表示有t个实例

第二行起,每行输入一个表达式,每个表达式末尾带#表示结束

输入t行

输出

每行输出一个表达式的计算结果,计算结果用浮点数(含2位小数)的格式表示

参考代码如下:

#include <iostream>
#include<iomanip>
using namespace std;

int main()

{ double temp = 12.345678

  cout<<fixed<<setprecision(2)<<temp<<endl;

}

输出结果为12.35

输入样例:

2
1+2*3-4/5#
(66+(((11+22)*2-33)/3+6)*2)-45.6789#

输出样例

6.20
54.32 

思路分析

这道题最重要的就是要把表达式转换成后缀表达式。比如,原表达式是= a * b + (c - d / e) * f就变为a b * c d e / - f * +    ,这样运算符出现的顺序就正好是实际运算的顺序。那么怎么样把原表达式变为后缀表达式呢?用两个栈OPTR和OPND来分别运算符和数值,遍历表达式,当遇见数值时,直接入OPND。遇见运算符时,比较该运算符与栈顶运算符的优先级顺序,若该运算符的优先级高,入栈;否则,将OPND的上两个数取出来进行运算,并把运算结果存入OPND栈顶。

当读到#时说明该表达式结束,OPND中的元素就是最终的计算结果。

AC代码

  1. #include <iostream>
  2. #include <string>
  3. #include <cstring>
  4. #include <stack>
  5. #include <iomanip>
  6. using namespace std;
  7. #define OPSETSIZE 7
  8. unsigned char Prior[7][7] = { //运算符间的优先关系
  9. '>','>','<','<','<','>','>',
  10. '>','>','<','<','<','>','>',
  11. '>','>','>','>','<','>','>',
  12. '>','>','>','>','<','>','>',
  13. '<','<','<','<','<','=',' ',
  14. '>','>','>','>',' ','>','>',
  15. '<','<','<','<','<',' ','='
  16. };
  17. char OPSET[OPSETSIZE]={'+' , '-' , '*' , '/' ,'(' , ')' , '#'}; //运算符集合
  18. double Operate(double a, unsigned char theta, double b); //计算类似a+b的表达式结果
  19. bool In(char Test, char* TestOp); //判断字符Test是否是运算符,是则返回true
  20. char precede(char Aop, char Bop); //返回两个运算符优先级的比较结果
  21. //以下完成算术表达式求值函数EvaluateExpression(string MyExp)的填空
  22. double EvaluateExpression(string MyExp) //算术表达式求值算法
  23. //设OPTR和OPND分别为运算符栈和运算数栈
  24. //参数MyExp是表达式字符串
  25. { stack<char> OPTR; //运算符栈,字符元素
  26. stack<double> OPND; //运算数栈,实数元素
  27. char TempData[20];
  28. double Data,a,b, r;
  29. char theta, c,x,Dr[2];
  30. OPTR.push('#');
  31. strcpy(TempData,"\0");
  32. int i=0; //表达式字符串的当前字符位置
  33. c = MyExp[i]; //表达式字符串的当前字符
  34. //逐个读入表达式字符串的字符到变量c,并识别为数值或运算符,做相应处理
  35. while (c!='#'||OPTR.top()!='#') {
  36. // if (c == '#') {
  37. // // return OPND.top();
  38. // break;
  39. // }
  40. // if (OPTR.top() == '#') {
  41. // // return OPND.top();
  42. // break;
  43. // }
  44. if (In(c, Dr)) {
  45. switch (precede(OPTR.top(), c)) {
  46. case '<':
  47. OPTR.push(c);
  48. i++;
  49. c = MyExp[i];
  50. break;
  51. case '=':
  52. OPTR.pop();
  53. i++;
  54. c = MyExp[i];
  55. break;
  56. case '>': {
  57. theta = OPTR.top();
  58. OPTR.pop();
  59. b = OPND.top();
  60. OPND.pop();
  61. a = OPND.top();
  62. OPND.pop();
  63. OPND.push(Operate(a, theta, b));
  64. break;
  65. }
  66. }
  67. } else {
  68. string str;
  69. int k=0;
  70. while (1) {
  71. if (In(MyExp[i], Dr)) {
  72. TempData[k]='\0';
  73. break;
  74. }
  75. else {
  76. TempData[k]=MyExp[i];
  77. i++;
  78. k++;
  79. c=MyExp[i];
  80. }
  81. }
  82. sscanf(TempData, "%lf", &Data);
  83. OPND.push(Data);
  84. }
  85. }
  86. return OPND.top();
  87. } //这是函数EvaluateExpression的右花括号
  88. //函数EvaluateExpression的代码到此结束
  89. //以下填空完成其他函数的定义,包括函数Operate\函数In\函数precede
  90. //可以参考教材光盘中文件夹CHAP03的源代码ALGO0304.cpp,几乎照抄
  91. double Operate(double a, unsigned char theta, double b) {
  92. switch (theta) {
  93. case '+':
  94. return a + b;
  95. break;
  96. case '-':
  97. return a - b;
  98. break;
  99. case '*':
  100. return a * b;
  101. break;
  102. case '/':
  103. return a / b;
  104. break;
  105. default :
  106. break;
  107. }
  108. }
  109. bool In(char Test, char* TestOp) {
  110. for (int i = 0; i < OPSETSIZE; i++) {
  111. if (Test == OPSET[i]) return true;
  112. }
  113. return false;
  114. }
  115. char precede(char Aop, char Bop) {
  116. int a, b;
  117. for (int i = -0; i < OPSETSIZE; i++) {
  118. if (Aop == OPSET[i]) a = i;
  119. if (Bop == OPSET[i]) b = i;
  120. }
  121. return Prior[a][b];
  122. }
  123. //主函数
  124. int main()
  125. { string Exp;
  126. int t;
  127. double result;
  128. cin>>t;
  129. while (t--)
  130. { cin>>Exp;
  131. result=EvaluateExpression(Exp);
  132. cout<<fixed<<setprecision(2)<<result<<endl;
  133. }
  134. return 0;
  135. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/515632
推荐阅读
相关标签
  

闽ICP备14008679号