【Zhejiang University PATest】02-3. 求前缀表达式的值
算术表达式有前缀表示法、中缀表示法和后缀表示法等形式。前缀表达式指二元运算符位于两个运算数之前,例如2+3*(7-4)+8/4的前缀表达式是:+ + 2 * 3 - 7 4 / 8 4。请设计程序计算前缀表达式的结果值。
输入格式说明:
输入在一行内给出不超过30个字符的前缀表达式,只包含+、-、*、\以及运算数,不同对象(运算数、运算符号)之间以空格分隔。
输出格式说明:
输出前缀表达式的运算结果,精确到小数点后1位,或错误信息“ERROR”。
样例输入与输出:
| 序号 | 输入 | 输出 |
| 1 |
+ + 2 * 3 - 7 4 / 8 4 |
13.0 |
| 2 |
/ -25 + * - 2 3 4 / 8 4 |
12.5 |
| 3 |
/ 5 + * - 2 3 4 / 8 2 |
ERROR |
| 4 |
+10.23 |
10.2 |
【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 ...
随机推荐
- hduoj-----(1068)Girls and Boys(二分匹配)
Girls and Boys Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) ...
- Java 集合系列 13 WeakHashMap
java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...
- ThinkPHP中数据库操作返回值总结
转自:http://www.baiwar.com/post/thinkphp-database-operations-in-the-return-value.html Thinkphp中的Think\ ...
- vs2016 vsto excel addin deploy error: vsto 无法解析属性type的值
https://social.msdn.microsoft.com/Forums/vstudio/en-US/ea33e391-21d7-4f54-92cb-c7af72f19c61/outlook- ...
- [转]C#中的Monitor类
object obj=new object(); Monitor在锁对象obj上会维持两个线程队列R和W以及一个引用T : (1) T是对当前获得了obj锁的线程的引用(设此线程为CurrThread ...
- 实现OAUTH协议 实现 QQ 第三方登录效果
1.OAuth的简述 OAuth(Open Authorization,开放授权)是为用户资源的授权定义了一个安全.开放及简单的标准,第三方无需知道用户的账号及密码,就可获取到用户的授权信息,并且这是 ...
- 无需激活用户直接登入discuz
//打开discuz/api/uc.php //synlogin方法(180行)处,往下找到 if(($member = getuserbyuid($uid, 1))) { dsetcookie('a ...
- spring mvc重定向页面
@RequestMapping(value="/del/{id}") public String delUser(@PathVariable int id){ return &qu ...
- ubuntu 14.04 安装截图工具 Shutter及使用
一.安装截图工具 Shutter 1. 添加安装包软件源 sudo add-apt-repository ppa:shutter/ppa 1 2. 更新源并安装 shutter sudo apt-ge ...
- ng-repeat的group
http://blog.csdn.net/violet_day/article/details/17023219 一.obj包含 <!doctype html> <html ng- ...