数学表达式求值

骑猪看日落 2022-06-02 08:00 398阅读 0赞





















成绩 10 开启时间 2017年10月18日 星期三 17:40
折扣 0.8 折扣时间 2017年11月8日 星期三 23:55
允许迟交 关闭时间 2018年01月8日 星期一 23:55

问题描述

  带有变量的中缀表达式是常见的数学表达式。如果规定变量由长度不超过 8 个小写字母组成;end为保留字,表示程序段结束;用?表示输出指定变量的值,则可以设计出比较复杂的表达式(即一个可顺序执行语句序列)。例如,如果有如下语句段:

abc=10
def=8
c=abc+def
abc=abc+5-c*2
? c
? abc
end

则输出为:

c=18
abc=-21

注意:为了简化编程实现,运算符只有+,-,*,/ ,%和^(指数运算),可以处理圆括号(),并假定输入的算术表达式正确。

要求:使用栈结构实现。

输入:表达式序列

输出:全部指定变量的值

表达式中的全部计算结果均为整数。如果在计算过程中出现除数为0的情况,则输出:Divide 0.

特殊情况说明:
在表达式中,如果操作数出现负数(例如-8),则要特别注意。例如:
10加-8表示为:10+-8。
10减-8表示为:10—8。






























































  测试输入关于“测试输入”的帮助 期待的输出关于“期待的输出”的帮助 时间限制关于“时间限制”的帮助 内存限制关于“内存限制”的帮助 额外进程关于“{$a} 个额外进程”的帮助
测试用例 1 以文本方式显示


  1. abc=10↵

  2. def=8↵

  3. c=abc+def↵

  4. abc=abc+5-c2↵

  5. ? c↵

  6. ? abc↵

  7. end↵


以文本方式显示


  1. c=18↵

  2. abc=-21↵


1秒 64M 0
测试用例 2 以文本方式显示


  1. a=12↵

  2. b=5↵

  3. c=a/b↵

  4. d=(a+1)%(b+1)↵

  5. e=a^2↵

  6. f=-12+a↵

  7. g=(a+5)d-c↵

  8. ? c↵

  9. ? d↵

  10. ? e↵

  11. ? f↵

  12. ? g↵

  13. a=a+10↵

  14. ? a↵

  15. end↵


以文本方式显示


  1. c=2↵

  2. d=1↵

  3. e=144↵

  4. f=0↵

  5. g=15↵

  6. a=22↵


1秒 64M 0
测试用例 3 以文本方式显示


  1. abc=3↵

  2. ab=2^(abc-1)^(5-abc)↵

  3. ? ab↵

  4. end↵


以文本方式显示


  1. ab=16↵


1秒 64M 0
测试用例 4 以文本方式显示


  1. a=2↵

  2. b=a^(a+1)^(10-8)↵

  3. ? b↵

  4. end↵


以文本方式显示


  1. b=512↵


1秒 64M 0
测试用例 5 以文本方式显示


  1. a=10↵

  2. ? a↵

  3. b=-10+10↵

  4. ? b↵

  5. a=-10-10↵

  6. ? a↵

  7. c=a+-10+-10↵

  8. ? c↵

  9. d=-20+-8-8↵

  10. ? d↵

  11. e=a-12-2↵

  12. ? e↵

  13. f=80—10+2↵

  14. ? f↵

  15. g=-10—10↵

  16. ? g↵

  17. h=-10+-10↵

  18. ? h↵

  19. i=(90)↵

  20. ? i↵

  21. k=(-100)↵

  22. ? k↵

  23. end↵


以文本方式显示


  1. a=10↵

  2. b=0↵

  3. a=-20↵

  4. c=-40↵

  5. d=-36↵

  6. e=4↵

  7. f=92↵

  8. g=0↵

  9. h=-20↵

  10. i=90↵

  11. k=-100↵


1秒 64M 0
测试用例 6 以文本方式显示


  1. abcdefgh=4↵

  2. ten=10↵

  3. a=18-32↵

  4. ? a↵

  5. b=18/abcdefgh↵

  6. ? b↵

  7. c=18%(b-1)↵

  8. ? c↵

  9. d=ten+(ten+ten)abcdefgh↵

  10. ? d↵

  11. e=ten-2ten/abcdefgh↵

  12. ? e↵

  13. f=(18-3)3↵

  14. ? f↵

  15. ten=ten(ten)↵

  16. ? ten↵

  17. ten=ten/10↵

  18. ten=(ten+2)/(8-ten)↵

  19. ? ten↵

  20. h=(23)/(52)↵

  21. ? h↵

  22. ten=10↵

  23. x=ten-(80-30)/33+abcdefgh↵

  24. y=(((2+8)2-(2+abcdefgh)/2)2-8)2↵

  25. z=(((8+2)(abcdefgh/2)))↵

  26. ? x↵

  27. ? y↵

  28. ? z↵

  29. end↵


以文本方式显示


  1. a=-14↵

  2. b=4↵

  3. c=0↵

  4. d=90↵

  5. e=5↵

  6. f=45↵

  7. ten=100↵

  8. ten=-6↵

  9. h=0↵

  10. x=-34↵

  11. y=52↵

  12. z=20↵


1秒 64M 0
  1. #include<cstdio>
  2. #include<string>
  3. #include<map>
  4. #include<stack>
  5. #include<math.h>
  6. #include<iostream>
  7. using namespace std;
  8. map<string, int> Varible;
  9. stack<char> Op;
  10. stack<int> Opnum;
  11. string Instruction;
  12. string tmp;
  13. int GetproiIncoming(char c) //栈外的优先级
  14. {
  15. switch (c)
  16. {
  17. case('+') : return 3;
  18. case('-') : return 3;
  19. case('*') : return 5;
  20. case('/') : return 5;
  21. case('%') : return 5;
  22. case('(') : return 10;
  23. case('^') : return 8;
  24. }
  25. }
  26. int GetproInstack(char c) //栈内的优先级
  27. {
  28. switch (c)
  29. {
  30. case('+') : return 4;
  31. case('-') : return 4;
  32. case('*') : return 6;
  33. case('/') : return 6;
  34. case('%') : return 6;
  35. case('(') : return 1;
  36. case('^') : return 7;
  37. }
  38. }
  39. int comput(char c, int a, int b)
  40. {
  41. switch (c)
  42. {
  43. case('+') : return a+b;
  44. case('-') : return a-b;
  45. case('*') : return a*b;
  46. case('/') : return a/b;
  47. case('%') : return a%b;
  48. case('^') : return (int)pow(double(a),double(b));
  49. }
  50. }
  51. int Getvar(string tmp)
  52. {
  53. int num = 0;
  54. for (int i = 0; tmp[i]; i++)
  55. {
  56. if (tmp[i] >= '0'&&tmp[i] <= '9')
  57. {
  58. num = num * 10 + tmp[i] - '0';
  59. }
  60. else if (tmp[i] >= 'a'&&tmp[i] <= 'z')
  61. {
  62. string var;
  63. int k = i;
  64. while (tmp[k] >= 'a'&&tmp[k] <= 'z')
  65. {
  66. k++;
  67. }
  68. var = tmp.substr(i, k-i);
  69. Opnum.push(Varible[var]);
  70. i = k - 1;
  71. }
  72. else if (!(tmp[i] >= '0'&&tmp[i] <= '9') && !(tmp[i] >= 'a'&&tmp[i] <= 'z'))
  73. {
  74. if (tmp[i] == '=') continue;
  75. if ((tmp[i - 1] >= '0'&&tmp[i - 1] <= '9'))
  76. {
  77. Opnum.push(num); num = 0;
  78. }
  79. else if (!(tmp[i - 1] >= '0'&&tmp[i - 1] <= '9') && !(tmp[i - 1] >= 'a'&&tmp[i - 1] <= 'z')&&(tmp[i]=='+'||tmp[i]=='-'))
  80. {
  81. i++; int k = i;
  82. while (tmp[k] && (tmp[k] >= '0'&&tmp[k] <= '9'))
  83. {
  84. num = num * 10 + tmp[k] - '0'; k++;
  85. }
  86. if (tmp[i - 1] == '-') num *= -1; i = k - 1; continue;
  87. }
  88. if (Op.empty()||tmp[i]=='(')
  89. {
  90. Op.push(tmp[i]); continue;
  91. }
  92. else if (tmp[i] == ')')
  93. {
  94. char op;
  95. while (!Op.empty() && (op = Op.top()) != '(')
  96. {
  97. int b = Opnum.top(); Opnum.pop();
  98. int a = Opnum.top(); Opnum.pop();
  99. if (b == 0 && op == '/')
  100. continue;
  101. else { Opnum.push(comput(op,a,b)); }
  102. Op.pop();
  103. }
  104. Op.pop();
  105. }
  106. else
  107. {
  108. int Incoming = GetproiIncoming(tmp[i]);
  109. int Instack;
  110. char op;
  111. while (!Op.empty()&&(Instack = GetproInstack(Op.top())) > Incoming)
  112. {
  113. op = Op.top();
  114. int b = Opnum.top(); Opnum.pop();
  115. int a = Opnum.top(); Opnum.pop();
  116. if (b == 0 && op == '/')
  117. continue;
  118. else { Opnum.push(comput(op, a, b)); }
  119. Op.pop();
  120. }
  121. Op.push(tmp[i]);
  122. }
  123. }
  124. }
  125. if (tmp[tmp.length()-1] >= '0'&&tmp[tmp.length()-1] <= '9')
  126. Opnum.push(num);
  127. if (!Op.empty()||!Opnum.empty())
  128. {
  129. while (!Op.empty())
  130. {
  131. char op = Op.top();
  132. int b = Opnum.top(); Opnum.pop();
  133. int a = Opnum.top(); Opnum.pop();
  134. if (b == 0 && op == '/')
  135. continue;
  136. else { Opnum.push(comput(op, a, b)); }
  137. Op.pop();
  138. }
  139. return Opnum.top();
  140. }
  141. else return num;
  142. }
  143. int main()
  144. {
  145. //freopen("1.txt", "r", stdin);
  146. while (getline(cin,Instruction))
  147. {
  148. if (Instruction == "end")
  149. break;
  150. while (!Op.empty())
  151. Op.pop();
  152. while (!Opnum.empty())
  153. Opnum.pop();
  154. if (Instruction[0] == '?')
  155. {
  156. tmp = Instruction.substr(2);
  157. int num = Varible.find(tmp)->second;
  158. cout << tmp<< '='<<num<< endl;
  159. }
  160. else if (Instruction[0] >= 'a'&&Instruction[0] <= 'z')
  161. {
  162. int i = 0;
  163. string varble;
  164. while (Instruction[i] != '=')
  165. {
  166. i++;
  167. }
  168. varble = Instruction.substr(0, i);
  169. if (Varible.count(varble) == 0)
  170. {
  171. Varible[varble] = 0;
  172. }
  173. string tmp = Instruction.substr(i);
  174. Varible[varble] = Getvar(tmp);
  175. }
  176. }
  177. return 0;
  178. }

发表评论

表情:
评论列表 (有 0 条评论,398人围观)

还没有评论,来说两句吧...

相关阅读

    相关 表达式

    中缀表达式:日常生活中我们见到的表达式 前缀表达式:运算符位于两个操作数之前 后缀表达式:运算符位于两个操作数之后 中缀表达式转化为后缀表达式: ![watermark

    相关 算法 表达式

    重中之重,这个博客还是有bug的,请转看逆波兰表达式(自认为当时写的还不错) 表达式求值中用到了两个栈,一个栈存放的是操作数,另一个栈存放的是操作符(运算符号和\),\可以让

    相关 表达式

    今天把表达式求值给搞定吧。 问题:给你个表达式,有加减乘除和小括号,让算出结果。 我们假定计算式是正确的,并且不会出现除数为0等错误。 py大法好啊,在保证可读性的前提下