算术表达式有前缀表示法、中缀表示法和后缀表示法等形式。前缀表达式指二元运算符位于两个运算数之前,例如2+3*(7-4)+8/4的前缀表达式是:+ + 2 * 3 - 7 4 / 8 4。请设计程序计算前缀表达式的结果值。

输入格式说明:

输入在一行内给出不超过30个字符的前缀表达式,只包含+、-、*、\以及运算数,不同对象(运算数、运算符号)之间以空格分隔。

输出格式说明:

输出前缀表达式的运算结果,精确到小数点后1位,或错误信息“ERROR”。

样例输入与输出:

序号 输入 输出
1
  1. + + 2 * 3 - 7 4 / 8 4
  1. 13.0
2
  1. / -25 + * - 2 3 4 / 8 4
  1. 12.5
3
  1. / 5 + * - 2 3 4 / 8 2
  1. ERROR
4
  1. +10.23
  1. 10.2

【solution】

前缀表达式的求值,算法并不难,我觉得更难的地方是字符串的处理以及一些细节的地方,比较花时间。

算法如下:

“对于一个前缀表达式的求值而言,首先要从右至左扫描表达式,从右边第一个字符开始判断,如果当前字符是数字则一直到数字串的末尾再记录下来,如果是运算符, 则将右边离得最近的两个“数字串”作相应的运算,以此作为一个新的“数字串”并记录下来。一直扫描到表达式的最左端时,最后运算的值也就是表达式的值。例 如,前缀表达式“- 1 + 2 3“的求值,扫描到3时,记录下这个数字串,扫描到2时,记录下这个数字串,当扫描到+时,将+右移做相邻两数字串的运算符,记为2+3,结果为5,记录下这个新数字串,并继续向左扫描,扫描到1时,记录下这个数字串,扫描到-时,将-右移做相邻两数字串的运算符,记为1-5,结果为-4,所以表达式的值为-4。”——来自百度百科词条“前缀表达式”

按照这个算法用栈写出来就可以了,时间复杂度 O(n)。

AC的代码如下:

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include <math.h>
  5.  
  6. #define exception();\
  7. printf("ERROR");\
  8. exit();
  9.  
  10. int contain(char ch)
  11. {
  12. if (ch=='+' || ch=='-' || ch=='*' || ch=='/') return ;
  13. return ;
  14. }
  15.  
  16. float calc(float a, float b, char ch)
  17. {
  18. float ans;
  19. switch (ch)
  20. {
  21. case '+':
  22. ans = a+b;
  23. break;
  24. case '-':
  25. ans = a-b;
  26. break;
  27. case '*':
  28. ans = a*b;
  29. break;
  30. case '/':
  31. if (b == ) { exception(); }
  32. ans = a/b;
  33. break;
  34. }
  35. return ans;
  36. }
  37.  
  38. float addbit(float ans, int boo, char ch, int power)
  39. {
  40. if (!boo) return (ans*+ch-'');
  41. else return (ans+(float)(ch-'')/pow(,power));
  42. }
  43.  
  44. float str2flo(char *ch)
  45. {
  46. float ans;
  47. int power = ;
  48. int boo = , positive = ;
  49.  
  50. if (*ch == '-')
  51. {
  52. ch++;
  53. positive = ;
  54. }
  55. else if (*ch == '+') ch++;
  56.  
  57. ans = *ch-'';
  58. ch++;
  59.  
  60. while (*ch != ' ' && *ch != '\0' && *ch != '\n')
  61. {
  62. if (*ch>='' && *ch<='')
  63. {
  64. if (boo) power++;
  65. ans = addbit(ans, boo, *ch, power);
  66. }
  67. else if (*ch=='.')
  68. {
  69. boo = ;
  70. }
  71. ch++;
  72. }
  73.  
  74. if (positive) return ans; else return -ans;
  75. }
  76.  
  77. int main()
  78. {
  79. char str[];
  80. int n, i, tail = ;
  81. float ans[];
  82. int boo = ;
  83.  
  84. gets(str);
  85.  
  86. n = strlen(str) - ;
  87.  
  88. while (n >= )
  89. {
  90. if ( contain(str[n]) )
  91. {
  92. if (tail < ) { exception(); }
  93. else
  94. {
  95. ans[tail-] = calc(ans[tail-], ans[tail-], str[n]);
  96. tail--;
  97. n = n - ;
  98. }
  99. }
  100. else if (str[n] != ' ')
  101. {
  102. while (str[n]!=' ' && n>=) n--;
  103. ans[tail++] = str2flo(str+n+);
  104. n--;
  105. }
  106. else n--;
  107. }
  108.  
  109. if (tail == )
  110. {
  111. printf("%.1f", ans[]);
  112. }
  113. else { exception(); }
  114.  
  115. return ;
  116. }

【Zhejiang University PATest】02-3. 求前缀表达式的值的更多相关文章

  1. pat02-线性结构3. 求前缀表达式的值(25)

    02-线性结构3. 求前缀表达式的值(25) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 算术表达式有前缀表示法.中缀表示法和后缀表示法 ...

  2. PTA笔记 堆栈模拟队列+求前缀表达式的值

    基础实验 3-2.5 堆栈模拟队列 (25 分) 设已知有两个堆栈S1和S2,请用这两个堆栈模拟出一个队列Q. 所谓用堆栈模拟队列,实际上就是通过调用堆栈的下列操作函数: int IsFull(Sta ...

  3. 3-07. 求前缀表达式的值(25) (ZJU_PAT数学)

    题目链接:http://pat.zju.edu.cn/contests/ds/3-07 算术表达式有前缀表示法.中缀表示法和后缀表示法等形式.前缀表达式指二元运算符位于两个运算数之前,比如2+3*(7 ...

  4. 信息竞赛进阶指南--递归法求中缀表达式的值,O(n^2)(模板)

    // 递归法求中缀表达式的值,O(n^2) int calc(int l, int r) { // 寻找未被任何括号包含的最后一个加减号 for (int i = r, j = 0; i >= ...

  5. openjduge 求简单表达式的值

    表达式求值 总时间限制:  10000ms  单个测试点时间限制:  1000ms  内存限制:  131072kB 给定一个只包含加法和乘法的算术表达式,请你编程计算表达式的值. 输入 输入仅有一行 ...

  6. K:双栈法求算术表达式的值

    相关介绍:  该算法用于求得一个字符串形式的表达式的结果.例如,计算1+1+(3-1)*3-(21-20)/2所得的表达式的值,该算法利用了两个栈来计算表达式的值,为此,称为双栈法,其实现简单且易于理 ...

  7. 【Zhejiang University PATest】02-1. Reversing Linked List

    Given a constant K and a singly linked list L, you are supposed to reverse the links of every K elem ...

  8. [LeetCode] Evaluate Division 求除法表达式的值

    Equations are given in the format A / B = k, where A and B are variables represented as strings, and ...

  9. [LeetCode] 399. Evaluate Division 求除法表达式的值

    Equations are given in the format A / B = k, where A and B are variables represented as strings, and ...

随机推荐

  1. (26)odoo中的序列运用

    * 模块中增加序列    __openerp__.py :    ...     'data': [        'product_data.xml',    ],    ...    ------ ...

  2. lucene Lock obtain timed out: Lock@

    出错界面: 解决办法: 出现以上异常主要有两种原因: 1.系统正在写索引未完成之前,应用程序关闭 解决方法:删除提示的lock文件后重启应用(最好在应用中捕捉到,自动删除) 2.系统中有多个线程或程序 ...

  3. .NET GC机制学习笔记

    学习笔记内容来自网络资料摘录http://www.cnblogs.com/springyangwc/archive/2011/06/13/2080149.html 1.GC介绍 Garbage Col ...

  4. 安装VC6提示找不到ACME时的解决办法

    将安装程序COPY到电脑上1.打开setupwiz.ini,把"acme=acmboot.exe"改为"=acmsetup.exe";2.STF=setup/v ...

  5. 500 TypeError: Cannot read property 'connect.sid' of undefined

    1:在写passport验证测试用例时,发现有几个引用中间件顺序的错误,检查发现,passport验证写的是session,在传错误信息的时候req.flash调用也需要用到session中间件,否则 ...

  6. 关于C#迭代器

    >1 IEnumerator与IEnumerable IEnumerator与IEnumerable两个接口是用于实现迭代器的接品只要实现了IEnumerable就可以用foreach,linq ...

  7. 216. Combination Sum III——本质DFS

    Find all possible combinations of k numbers that add up to a number n, given that only numbers from ...

  8. String.resize()

    void resize (size_t n); void resize (size_t n, char c); 测试代码: // resizing string #include <iostre ...

  9. C#伪静态实现的方法

    在asp.net开发网站的时候,我们经常会用到伪静态,好处是可以隐藏真实的路径,提高网站的安全性,在官网等展示网站希望对搜索引擎友好,提高搜索排名:或者在涉及到模板开发都会用到伪静态.下面讲解下平时用 ...

  10. bzoj 2744: [HEOI2012]朋友圈

    #include<cstdio> #include<iostream> #define M 3010 using namespace std; ],u[M*M>>] ...