nyoj35——逆波兰表达式
逆波兰表达式又称作后缀表达式,在四则混合运算的程序设计中用到。
例如:
1+2写成后缀表达式就是12+
4+5*(3-2)的后缀表达式就是4532-*+
后缀表达式在四则运算中带来了意想不到的方便,在生成过程中自动保持了优先级;
生成逆波兰表达式的算法如下:
我们首先的用两个栈结构来存储运算符和操作数;
从做到右遍历我们输入的中缀表达式:
1、如果是操作数的话,那么就直接压入存放操作数的堆栈;
2、如果是"("左括号的话,那么就直接压入存放运算符的堆栈;
3、如果是")"右括号的话,那么就从运算符堆栈中弹数据,并将弹出的数据压入到操作数堆栈中,直到遇到"("为止,这里值得注意的是,"("是必须要从运算符堆栈中弹出的,但是不压入到操作数堆栈,后缀表达式中是不包含括号的;
4、如果是其他符号,就是其他的运算符+-*/这些,那么就:
a、如果运算符堆栈为空,则直接压入运算符堆栈;
b、如果不为空且此时运算符堆栈的栈顶元素为括号,包括左括号和右括号,那么也是直接压入运算符堆栈中;
c、如果此时遍历到的元素的优先级比此时运算符堆栈栈顶元素的优先级高,则直接压入运算符堆栈;
d、如果正在遍历的元素的优先级和运算符堆栈栈顶的元素的优先级相等或者更小,则需要将栈顶元素弹出并且放到操作数堆栈中,并且将正在遍历的元素压入到运算符堆栈,其实运算符堆栈中的元素顺序就是优先级的顺序;
5、直到遍历完表达式,此时还需要将运算符堆栈中的所有元素压入到操作数堆栈中,算法完成。
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
根据以上算法可以得到逆波兰表达式,我们得到逆波兰表达式之后,必须求得正确的计算结果,有了逆波兰表达式,计算起来就攘夷多了,算法如下:
用另一个堆栈来保存数据,从左到右遍历逆波兰表达式:
1、如果是数字,则直接压入堆栈中;
2、如果是运算符(+,-,*,/),则弹出堆栈中的两个数据,进行相应的计算,计算完成之后得到一个数据,然后又压入堆栈中;
3、直到遍历完成,此时堆栈中的数据就是最后计算的结果,简单吧
以上摘自:https://blog.csdn.net/uestclr/article/details/50630906
AC代码:
#include <bits/stdc++.h>
using namespace std; int prio(char x) //定义优先级
{
switch (x){
case '+': return ;
case '-': return ;
case '*': return ;
case '/': return ;
default : return ; //默认会出现括号,而如果有括号都得压进去
}
} int main()
{
int t;
cin >> t;
while(t--){
stack<char>s;
stack<double>d;
string s1,s2;
cin >> s1;
int i=;
s2 = "";
s.push('#');
while(i < s1.length()-){ // 等于号 不用扫描
if('(' == s1[i]){
s.push(s1[i++]);
}
else if(')' == s1[i]){
while(s.top() != '('){
s2 += s.top();
s2 += ' '; //加空格是为了计算时的方便
s.pop();
}
s.pop();//把左括号弹出
i++;
}
else if(s1[i] == '+'||s1[i] == '-'||s1[i] == '*'||s1[i] == '/'){
while(prio(s.top()) >= prio(s1[i])){
s2 += s.top();
s2 += ' ';
s.pop();
}
s.push(s1[i]);
i++;
}
else{//如果是数字类
while(s1[i] >= ''&&s1[i] <= ''||s1[i] == '.'){
s2 += s1[i++];
}
s2 += ' ';
}
}
while(s.top() != '#'){ //当表达式扫描完,栈中还有剩余符号
s2 += s.top();
s2 += ' ';
s.pop();
} // cout << s2 << endl; double result = ;
i = ;
while(i < s2.length()){
switch (s2[i]){
case '+':
result = d.top();
d.pop();
result += d.top();
d.pop();
i++;
break;
case '-':
result = d.top();
d.pop();
result = d.top() - result;
d.pop();
i++;
break;
case '*':
result = d.top();
d.pop();
result *= d.top();
d.pop();
i++;
break;
case '/':
result = d.top();
d.pop();
result = d.top()/result;//注意因为是栈,所以除法的顺序发生变化
d.pop();
i++;
break;
default:
result = ;
double fac = 10.0;
while(s2[i] >= ''&&s2[i] <= ''){
result = result* + s2[i] - '';
i++;
}
if(s2[i++] == '.'){
while(s2[i] >= ''&&s2[i] <= ''){
result += (s2[i] - '')/fac;
fac *= ;
i++;
}
}
}
// cout << result << endl;
d.push(result);
while(s2[i] == ' '){
i++;
}
}
printf("%.2lf\n",d.top());
}
return ;
}
——
nyoj35——逆波兰表达式的更多相关文章
- [LeetCode] Evaluate Reverse Polish Notation 计算逆波兰表达式
Evaluate the value of an arithmetic expression in Reverse Polish Notation. Valid operators are +, -, ...
- AC日记——逆波兰表达式 openjudge 3.3 1696
1696:逆波兰表达式 总时间限制: 1000ms 内存限制: 65536kB 描述 逆波兰表达式是一种把运算符前置的算术表达式,例如普通的表达式2 + 3的逆波兰表示法为+ 2 3.逆波兰表达式 ...
- noi1696 逆波兰表达式
1696:逆波兰表达式 http://noi.openjudge.cn/ch0303/1696/ 总时间限制: 1000ms 内存限制: 65536kB 描述 逆波兰表达式是一种把运算符前置的算术 ...
- codevs5164 逆波兰表达式
题目描述 Description 逆波兰表达式是一种把运算符前置的算术表达式(又叫前缀表达式),例如普通的表达式2 + 3的逆波兰表示法为+ 2 3.逆波兰表达式的优点是运算符之间不必有优先级关系,也 ...
- lintcode 中等题:Evaluate Reverse Polish notation逆波兰表达式求值
题目 逆波兰表达式求值 在逆波兰表达法中,其有效的运算符号包括 +, -, *, / .每个运算对象可以是整数,也可以是另一个逆波兰计数表达. 样例 ["2", "1&q ...
- SDIBT2666——逆波兰表达式求值
逆波兰表达式求值(栈和队列) Description 从键盘上输入一个逆波兰表达式,用伪码写出其求值程序.规定:逆波兰表达式的长度不超过一行,以@符作为输入结束,操作数之间用空格分隔,操作符只可能有+ ...
- OpenJudge 2694 逆波兰表达式
1.链接地址: http://bailian.openjudge.cn/practice/2694/ 2.题目: 总时间限制: 1000ms 内存限制: 65536kB 描述 逆波兰表达式是一种把运算 ...
- 逆波兰表达式 java
描述 逆波兰表达式是一种把运算符前置的算术表达式,例如普通的表达式2 + 3的逆波兰表示法为+ 2 3.逆波兰表达式的优点是运算符之间不必有优先级关系, 也不必用括号改变运算次序,例如(2 + 3) ...
- c++实现将表达式转换为逆波兰表达式
https://github.com/Lanying0/lintcode 所属: 数据结构->线性结构->栈 问题: 给定一个表达式字符串数组,返回该表达式的逆波兰表达式(即去掉括号). ...
随机推荐
- mysql数据库从删库到跑路之mysq索引
一 介绍 为何要有索引? 一般的应用系统,读写比例在10:1左右,而且插入操作和一般的更新操作很少出现性能问题,在生产环境中,我们遇到最多的,也是最容易出问题的,还是一些复杂的查询操作,因此对查询语句 ...
- The Cheap KD 10 is my best shoe yet
10 years of anything is fairly huge Cheap KD 10, but adding something as great as Flyknit causes it ...
- PHP计算上一个月最后一天、当月最后一天、下一个月最后一天
上个月最后一天: $last_month_last_day = date('Y-m-t',strtotime('-1 month')); 当月最后一天: $first_day=date('Y-m-01 ...
- 受限的用户shell环境
有些特殊情况下需要实现将系统内普通用户限定在指定目录下,并且只能使用系统管理员设定的命令.lshell就是实现这样功能的一个神器. lshell提供了一个针对每个用户可配置的限制性shell,lshe ...
- 解决Ubuntu sudo apt-get install遇到的E: Sub-process /usr/bin/dpkg returned an error code (1)问题
如题,本人在安装samba等软件的时候,在命令行敲入: sudo apt-get install samba4命令的时候,系统在下载之后报错,大致内容如下: ~$ sudo apt-get insta ...
- 20145328 《Java程序设计》第3周学习总结
20145328 <Java程序设计>第3周学习总结 教材学习内容总结 第四章 对象Object:存在的具体实体,具有明确的状态和行为 类Class:具有相同属性和行为的一组对象的集合,用 ...
- 20145331 《Java程序设计》第3周学习总结
20145331 <Java程序设计>第3周学习总结 教材学习内容总结 第四章 认识对象 •对象(Object):存在的具体实体,具有明确的状态和行为 •类(Class):具有相同属性和行 ...
- tiny4412的烧录工具minitool安装【学习笔记】
烧录了半天,在win10下一直就是烧录不进去,但是在Ubuntuh环境却可以,找了很久终于找到了,原来在win10安装minitool驱动的时候没有注意到报了错误,错误内容是驱动的数字签名问题,后来禁 ...
- [Linux]pycharm在Linux环境下安装
之前转载了一个在Windows环境下pycharm专业破解的安装的文章,今天为了在Linux环境下安装使用odoo10,所以尝试在Linux环境下安装pycharm专业破解版看看. windows下安 ...
- HDU5324 cqd分治
HDU5324 cqd分治 标签(空格分隔): 未分类 给你两个长度相同数列,求第一个不上升,第二个不下降的最长子序列长度. 这里要求的子序列对第一个和第二个来说是相同的.即如果你在第一个序列里选了第 ...