求前缀表达式的值 - 栈-pta天梯赛练习题
2017-03-18 17:58
537 查看
求前缀表达式的值
算术表达式有前缀表示法、中缀表示法和后缀表示法等形式。前缀表达式指二元运算符位于两个运算数之前,例如
解题思路
首先了解一下前缀表达式
前缀表达式就是不含括号的算术表达式,而且它是将运算符写在前面,
操作数写在后面的表达式,也称为“波兰式”。例如,- 1 + 2 3,它等价于1-(2+3);
前缀表达式如何求值
对于一个前缀表达式的求值而言,首先要从右至左扫描表达式,从右边第一个字符开始判断,如果当前字符是数字则一直到数字串的末尾再记录下来,如果是运算符,则将右边离得最近的两个“数字串”作相应的运算,以此作为一个新的“数字串”并记录下来。一直扫描到表达式的最左端时,最后运算的值也就是表达式的值。
例如,前缀表达式“- 1 + 2 3“的求值,扫描到3时,记录下这个数字串,扫描到2时,记录下这个数字串,当扫描到+时,将+右移做相邻两数字的运算符,记为2+3,结果为5,记录下这个新数字串,并继续向左扫描,扫描到1时,记录下这个数字串,扫描到-时,将-右移做相邻两数字串的运算符,记为1-5,结果为-4,
所以表达式的值为-4。
前缀表达式有什么用处
前缀表达式是一种十分有用的表达式,它将中缀表达式转换为可以依靠简单的操作就能得到运算结果的表达式。例如,(a+b)*(c+d)转换为 *,+,a,b,+,c,d。它的优势在于只用两种简单的操作,入栈和出栈就可以解决任何中缀表达式的运算。其运算方式为:如果当前字符(或字符串)为数字或变量,则压入栈内;如果是运算符,则将栈顶两个元素弹出栈外并作相应运算,再将结果压入栈内。当前缀表达式扫描结束时,栈里的就是中缀表达式运算的最终结果。(https://wenku.baidu.com/view/5664602d647d27284b7351f7.html)
如何解这道题目
既然知道了如何计算前缀表达式,但是麻烦的是如何处理数据?
看了网上很多人的代码,觉得写的都不太简练,这里想到了一种比较简洁的处理方式,使用c++的string和c语言的 atof()函数 。
代码
算术表达式有前缀表示法、中缀表示法和后缀表示法等形式。前缀表达式指二元运算符位于两个运算数之前,例如
2+3*(7-4)+8/4的前缀表达式是:
+ + 2 * 3 - 7 4 / 8 4。请设计程序计算前缀表达式的结果值。
输入格式:
输入在一行内给出不超过30个字符的前缀表达式,只包含+、
-、
*、
\以及运算数,不同对象(运算数、运算符号)之间以空格分隔。
输出格式:
输出前缀表达式的运算结果,保留小数点后1位,或错误信息ERROR。
输入样例:
+ + 2 * 3 - 7 4 / 8 4
输出样例:
13.0
解题思路
首先了解一下前缀表达式
前缀表达式就是不含括号的算术表达式,而且它是将运算符写在前面,
操作数写在后面的表达式,也称为“波兰式”。例如,- 1 + 2 3,它等价于1-(2+3);
前缀表达式如何求值
对于一个前缀表达式的求值而言,首先要从右至左扫描表达式,从右边第一个字符开始判断,如果当前字符是数字则一直到数字串的末尾再记录下来,如果是运算符,则将右边离得最近的两个“数字串”作相应的运算,以此作为一个新的“数字串”并记录下来。一直扫描到表达式的最左端时,最后运算的值也就是表达式的值。
例如,前缀表达式“- 1 + 2 3“的求值,扫描到3时,记录下这个数字串,扫描到2时,记录下这个数字串,当扫描到+时,将+右移做相邻两数字的运算符,记为2+3,结果为5,记录下这个新数字串,并继续向左扫描,扫描到1时,记录下这个数字串,扫描到-时,将-右移做相邻两数字串的运算符,记为1-5,结果为-4,
所以表达式的值为-4。
前缀表达式有什么用处
前缀表达式是一种十分有用的表达式,它将中缀表达式转换为可以依靠简单的操作就能得到运算结果的表达式。例如,(a+b)*(c+d)转换为 *,+,a,b,+,c,d。它的优势在于只用两种简单的操作,入栈和出栈就可以解决任何中缀表达式的运算。其运算方式为:如果当前字符(或字符串)为数字或变量,则压入栈内;如果是运算符,则将栈顶两个元素弹出栈外并作相应运算,再将结果压入栈内。当前缀表达式扫描结束时,栈里的就是中缀表达式运算的最终结果。(https://wenku.baidu.com/view/5664602d647d27284b7351f7.html)
如何解这道题目
既然知道了如何计算前缀表达式,但是麻烦的是如何处理数据?
看了网上很多人的代码,觉得写的都不太简练,这里想到了一种比较简洁的处理方式,使用c++的string和c语言的 atof()函数 。
代码
#include <iostream> #include <cstdio> #include <string> #include <cstring> #include <stack> #include <stdlib.h> using namespace std; stack <double> q; int main(){ string a[100]; bool error = 0; int n = 0; while(cin>>a[n++]){}///读到文件结尾自动结束 n -= 1;///注意这里n是个数,需要减一,可自己尝试确认 for(int i = n-1; i>=0; i--){ ///如果是符号 if(a[i].length() == 1 && (a[i][0]== '+' || a[i][0]=='-' || a[i][0]=='*' || a[i][0]=='/')){ if(q.size()<2) {error = 1; break;} double aa = q.top(); q.pop(); double bb = q.top(); q.pop(); if(a[i][0]== '+') q.push(aa+bb); else if(a[i][0]== '-') q.push(aa-bb); else if(a[i][0]== '*') q.push((aa*bb)); else if(a[i][0]== '/') { if(bb==0){error = 1; break;} q.push(aa/bb); } } else{ /// c_str() 函数是转化为字符数组 ///atof() 是c语言中将字符数组转化为浮点型数据函数 double x = atof(a[i].c_str()); q.push(x); } } if(q.size() != 1) error = 1; if(error) printf("ERROR"); else printf("%.1f",q.top()); return 0; }
相关文章推荐
- PTA 表达式转换 算术表达式有前缀表示法、中缀表示法和后缀表示法等形式。日常使用的算术表达式是采用中缀表示法,即二元运算符位于两个运算数中间。请设计程序将中缀表达式转换为后缀表达式。
- PTA 求前缀表达式的值 (25分)
- [数据结构]--PTA求前缀表达式的值
- 中缀表达式,后缀表达式,前缀表达式
- PAT天梯赛练习题——L3-007. 天梯地图(多边权SPFA)
- 前缀、中缀和后缀表达式
- PAT天梯赛练习题——L3-008. 喊山(邻接表+BFS)
- 中缀转前缀表达式
- \"preg_\" 为前缀的正则表达式常用操作函数——php
- 中缀表达式转换成前缀表达式和后缀表达式
- PAT 1130. Infix Expression (25) 前缀表达式、树的中序遍历
- 算法训练 前缀表达式
- 前序 中序 后序 遍历二叉树 - 前缀 中缀 后缀 表达式
- 7-19 求前缀表达式的值(25 分)---栈的运用
- 02-线性结构3. 求前缀表达式的值(25)
- PTA练习题---树的同构
- 02-3. 求前缀表达式的值(25)
- 前序 中序 后序 遍历二叉树 - 前缀 中缀 后缀 表达式
- 天梯赛练习题 L2-016. 愿天下有情人都是失散多年的兄妹 (bfs)
- 前缀表达式,后缀表达式