【Zhejiang University PATest】02-3. 求前缀表达式的值
算术表达式有前缀表示法、中缀表示法和后缀表示法等形式。前缀表达式指二元运算符位于两个运算数之前,例如2+3*(7-4)+8/4的前缀表达式是:+ + 2 * 3 - 7 4 / 8 4。请设计程序计算前缀表达式的结果值。
输入格式说明:
输入在一行内给出不超过30个字符的前缀表达式,只包含+、-、*、\以及运算数,不同对象(运算数、运算符号)之间以空格分隔。
输出格式说明:
输出前缀表达式的运算结果,精确到小数点后1位,或错误信息“ERROR”。
样例输入与输出:
序号 | 输入 | 输出 |
1 |
|
|
2 |
|
|
3 |
|
|
4 |
|
|
【solution】
前缀表达式的求值,算法并不难,我觉得更难的地方是字符串的处理以及一些细节的地方,比较花时间。
算法如下:
“对于一个前缀表达式的求值而言,首先要从右至左扫描表达式,从右边第一个字符开始判断,如果当前字符是数字则一直到数字串的末尾再记录下来,如果是运算符, 则将右边离得最近的两个“数字串”作相应的运算,以此作为一个新的“数字串”并记录下来。一直扫描到表达式的最左端时,最后运算的值也就是表达式的值。例 如,前缀表达式“- 1 + 2 3“的求值,扫描到3时,记录下这个数字串,扫描到2时,记录下这个数字串,当扫描到+时,将+右移做相邻两数字串的运算符,记为2+3,结果为5,记录下这个新数字串,并继续向左扫描,扫描到1时,记录下这个数字串,扫描到-时,将-右移做相邻两数字串的运算符,记为1-5,结果为-4,所以表达式的值为-4。”——来自百度百科词条“前缀表达式”
按照这个算法用栈写出来就可以了,时间复杂度 O(n)。
AC的代码如下:
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <math.h>
- #define exception();\
- printf("ERROR");\
- exit();
- int contain(char ch)
- {
- if (ch=='+' || ch=='-' || ch=='*' || ch=='/') return ;
- return ;
- }
- float calc(float a, float b, char ch)
- {
- float ans;
- switch (ch)
- {
- case '+':
- ans = a+b;
- break;
- case '-':
- ans = a-b;
- break;
- case '*':
- ans = a*b;
- break;
- case '/':
- if (b == ) { exception(); }
- ans = a/b;
- break;
- }
- return ans;
- }
- float addbit(float ans, int boo, char ch, int power)
- {
- if (!boo) return (ans*+ch-'');
- else return (ans+(float)(ch-'')/pow(,power));
- }
- float str2flo(char *ch)
- {
- float ans;
- int power = ;
- int boo = , positive = ;
- if (*ch == '-')
- {
- ch++;
- positive = ;
- }
- else if (*ch == '+') ch++;
- ans = *ch-'';
- ch++;
- while (*ch != ' ' && *ch != '\0' && *ch != '\n')
- {
- if (*ch>='' && *ch<='')
- {
- if (boo) power++;
- ans = addbit(ans, boo, *ch, power);
- }
- else if (*ch=='.')
- {
- boo = ;
- }
- ch++;
- }
- if (positive) return ans; else return -ans;
- }
- int main()
- {
- char str[];
- int n, i, tail = ;
- float ans[];
- int boo = ;
- gets(str);
- n = strlen(str) - ;
- while (n >= )
- {
- if ( contain(str[n]) )
- {
- if (tail < ) { exception(); }
- else
- {
- ans[tail-] = calc(ans[tail-], ans[tail-], str[n]);
- tail--;
- n = n - ;
- }
- }
- else if (str[n] != ' ')
- {
- while (str[n]!=' ' && n>=) n--;
- ans[tail++] = str2flo(str+n+);
- n--;
- }
- else n--;
- }
- if (tail == )
- {
- printf("%.1f", ans[]);
- }
- else { exception(); }
- return ;
- }
【Zhejiang University PATest】02-3. 求前缀表达式的值的更多相关文章
- pat02-线性结构3. 求前缀表达式的值(25)
02-线性结构3. 求前缀表达式的值(25) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 算术表达式有前缀表示法.中缀表示法和后缀表示法 ...
- PTA笔记 堆栈模拟队列+求前缀表达式的值
基础实验 3-2.5 堆栈模拟队列 (25 分) 设已知有两个堆栈S1和S2,请用这两个堆栈模拟出一个队列Q. 所谓用堆栈模拟队列,实际上就是通过调用堆栈的下列操作函数: int IsFull(Sta ...
- 3-07. 求前缀表达式的值(25) (ZJU_PAT数学)
题目链接:http://pat.zju.edu.cn/contests/ds/3-07 算术表达式有前缀表示法.中缀表示法和后缀表示法等形式.前缀表达式指二元运算符位于两个运算数之前,比如2+3*(7 ...
- 信息竞赛进阶指南--递归法求中缀表达式的值,O(n^2)(模板)
// 递归法求中缀表达式的值,O(n^2) int calc(int l, int r) { // 寻找未被任何括号包含的最后一个加减号 for (int i = r, j = 0; i >= ...
- openjduge 求简单表达式的值
表达式求值 总时间限制: 10000ms 单个测试点时间限制: 1000ms 内存限制: 131072kB 给定一个只包含加法和乘法的算术表达式,请你编程计算表达式的值. 输入 输入仅有一行 ...
- K:双栈法求算术表达式的值
相关介绍: 该算法用于求得一个字符串形式的表达式的结果.例如,计算1+1+(3-1)*3-(21-20)/2所得的表达式的值,该算法利用了两个栈来计算表达式的值,为此,称为双栈法,其实现简单且易于理 ...
- 【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 ...
- [LeetCode] Evaluate Division 求除法表达式的值
Equations are given in the format A / B = k, where A and B are variables represented as strings, and ...
- [LeetCode] 399. Evaluate Division 求除法表达式的值
Equations are given in the format A / B = k, where A and B are variables represented as strings, and ...
随机推荐
- (26)odoo中的序列运用
* 模块中增加序列 __openerp__.py : ... 'data': [ 'product_data.xml', ], ... ------ ...
- lucene Lock obtain timed out: Lock@
出错界面: 解决办法: 出现以上异常主要有两种原因: 1.系统正在写索引未完成之前,应用程序关闭 解决方法:删除提示的lock文件后重启应用(最好在应用中捕捉到,自动删除) 2.系统中有多个线程或程序 ...
- .NET GC机制学习笔记
学习笔记内容来自网络资料摘录http://www.cnblogs.com/springyangwc/archive/2011/06/13/2080149.html 1.GC介绍 Garbage Col ...
- 安装VC6提示找不到ACME时的解决办法
将安装程序COPY到电脑上1.打开setupwiz.ini,把"acme=acmboot.exe"改为"=acmsetup.exe";2.STF=setup/v ...
- 500 TypeError: Cannot read property 'connect.sid' of undefined
1:在写passport验证测试用例时,发现有几个引用中间件顺序的错误,检查发现,passport验证写的是session,在传错误信息的时候req.flash调用也需要用到session中间件,否则 ...
- 关于C#迭代器
>1 IEnumerator与IEnumerable IEnumerator与IEnumerable两个接口是用于实现迭代器的接品只要实现了IEnumerable就可以用foreach,linq ...
- 216. Combination Sum III——本质DFS
Find all possible combinations of k numbers that add up to a number n, given that only numbers from ...
- String.resize()
void resize (size_t n); void resize (size_t n, char c); 测试代码: // resizing string #include <iostre ...
- C#伪静态实现的方法
在asp.net开发网站的时候,我们经常会用到伪静态,好处是可以隐藏真实的路径,提高网站的安全性,在官网等展示网站希望对搜索引擎友好,提高搜索排名:或者在涉及到模板开发都会用到伪静态.下面讲解下平时用 ...
- bzoj 2744: [HEOI2012]朋友圈
#include<cstdio> #include<iostream> #define M 3010 using namespace std; ],u[M*M>>] ...