中缀表达式、前缀表达式、后缀表达式
中缀表达式、前缀表达式、后缀表达式
1)中缀表达式:操作运算符在操作数中间
(3+2)*4-6
2)前缀表达式:波兰式,操作运算符在操作数之前,
如-*+3246。
从右至左扫描表达式,遇到数字时,将数字压入堆栈,遇到运算符时,弹出栈顶的两个数,用运算符对它们做相应的计算(栈顶元素 op 次顶元素),并将结果入栈;重复上述过程直到表达式最左端,最后运算得出的值即为表达式的结果
中缀表达式 ----> 前缀表达式:
- 初始化两个栈,符号栈s1、存放中间结果栈s2- **从右至左扫描**中缀表达式- 遇到操作数,将其压入栈s2- 遇到操作运算符,则需要比较其与s1栈顶操作符的优先级1.若s1为空,或者栈顶运算符为**右括号)**,则直接入栈2.优先级高于栈顶运算符,也直接入栈3.否则,将s1栈顶运算符弹出压入s2,再转到步骤1进行判断- 遇到括号:1.如果遇到**右括号**,直接压入栈2.如果遇到**左括号**,则依次弹出s1栈顶运算符,压入s2,直到遇到右括号为止,并将这一对括号丢弃- 重复2-5,直至表达式左边- 将s1中剩余运算符依次弹出并压入s2- 依次弹出s2的元素,即为中缀表达式
例如:1+((2+3)×4)-5具体过程,如下表
扫描到的元素 | 中间结果栈s2(栈底->栈顶) | 运算符栈s1(栈底->栈顶) | 说明 |
---|---|---|---|
5 | 5 | 空 | 数字直接入栈s2 |
- | 5 | - | 运算符栈s1空,所以-直接入栈s2 |
) | 5 | -) | 右括号直接入栈s1 |
4 | 54 | - | 数字直接入栈s2 |
x | 54 | -)x | 符号栈顶为右括号,所以直接入栈s2 |
) | 54 | -)x) | 右括号直接入栈s1 |
3 | 543 | -)x) | 数字直接入栈s2 |
+ | 543 | -)x)+ | 符号栈顶为右括号,所以直接入栈s1 |
2 | 5432 | -)x)+ | 数字直接入栈s2 |
( | 5432+ | -)x | 左括号,所以将栈s1从顶部弹出元素,知道碰到右括号,同时将弹出的压入s2,另外这对括号将被抛弃 |
( | 5432+x | - | 左括号,所以将栈s1从顶部弹出元素,知道碰到右括号,同时将弹出的压入s2,另外这对括号将被抛弃 |
+ | 5432+x | -+ | +优先级和-优先级一样,所以直接入栈s1 |
1 | 5432+x1 | -+ | 数字直接入栈s2 |
将栈s1中剩余的依次弹出,并压入s2,得到 5432+x1+ -
最后将s2中依次弹出-+1x+2345
计算机计算值:
- 表达式: -*+3246- 从右至左扫描前缀表达式,依次将6、4、2、3依次压入堆栈- 遇到运算符 + ,弹出栈顶和次栈顶的两个数3、2,计算3+2的值为5,压入栈- 遇到*,依次弹出5、4,计算5*4为20,再将20压入堆栈- 遇到-,依次弹出20、6,计算20-6为14,即最后结果。
3)后缀表达式(逆波兰式):操作运算符在操作数之前,
如3 4 + 5 × 6 -。与前缀表达式类似,区别是从左至右扫描。
从左至右扫描表达式,遇到数字时,将数字压入堆栈,遇到运算符时,弹出栈顶的两个数,用运算符对它们做相应的计算(次顶元素 op 栈顶元素),并将结果入栈;重复上述过程直到表达式最右端,最后运算得出的值即为表达式的结果
中缀表达式 ----> 后缀表达式:
- 初始化两个栈,符号栈s1、存放中间结果栈s2- **从左至右**扫描中缀表达式- 遇到操作数,将其压入栈s2- 遇到操作运算符,则需要比较其与s1栈顶操作符的优先级1.若s1为空,或者栈顶运算符为**左括号(**,则直接入栈2.优先级高于栈顶运算符,也直接入栈3.否则,将s1栈顶运算符弹出压入s2,再转到步骤1进行判断- 遇到括号:1.如果遇到**左括号**,直接压入栈2.如果遇到**右括号**,则依次弹出s1栈顶运算符,压入s2,直到遇到右括号为止,并将这一对括号丢弃- 重复2-5,直至表达式右边- 将s1中剩余运算符依次弹出并压入s2- 依次弹出s2的元素,即为中缀表达式
例如:1+((2+3)×4)-5具体过程,如下表
扫描到的元素 | 中间结果栈s2(栈底->栈顶) | 运算符栈s1(栈底->栈顶) | 说明 |
---|---|---|---|
1 | 1 | 空 | 数字直接入栈s2 |
+ | 1 | + | 运算符栈s1空,所以-直接入栈s2 |
( | 1 | +( | 左括号直接入栈s1 |
( | 1 | +(( | 数字直接入栈s2 |
2 | 12 | +(( | 符号栈顶为左括号,所以直接入栈s2 |
+ | 12 | +((+ | 右括号直接入栈s1 |
3 | 123 | +((+ | 数字直接入栈s2 |
) | 123+ | +( | 符号栈顶为左括号,所以直接入栈s1 |
x | 123+ | +(x | 数字直接入栈s2 |
4 | 123+4 | +(x | 数字直接入栈s2 |
) | 123+4x | + | 右括号,所以从s1栈顶弹出元素并压入s2,直到遇到左括号,并且将这对括号抛弃 |
- | 123+4x | ± | 相同优先级,直接压入 |
5 | 123+4x5 | ± | 数字,直接压入s2 |
将栈s1中剩余的依次弹出,并压入s2,得到123+4x5-+(栈底->栈顶)
最后将s2中依次弹出±5x4+321
逆序 123+4x5-+,即为后缀表达式
计算机计算值:
- 表达式:3 4 + 5 × 6 -- 从左至右扫描后缀表达式,依次将3、4依次压入堆栈- 遇到运算符 + ,弹出栈顶和次栈顶的两个数4、3,计算4+3的值为7,压入栈- 遇到5,入栈- 遇到x,弹出栈顶和次栈顶的两个数5、7,计算7*5=35,入栈- 遇到6,入栈- 遇到-,弹出栈顶和次栈顶的两个数6、36,计算35-6=29
# java
public class Operation {private static int ADDITION=1;private static int SUBTRACTION=1;private static int MULTIPLICATION=2;private static int DIVISION=2;public static int getValue(String operation){int result;switch (operation){case "+":result=ADDITION;break;case "-":result=SUBTRACTION;break;case "*":result=MULTIPLICATION;break;case "/":result=DIVISION;break;default:
// System.out.println("不存在该运算符");result=0;}return result;}
}public class PolishNotation {public static void main(String[] args) {Scanner sc=new Scanner(System.in);System.out.println("请输入运算表达式:");String expressionStr=sc.nextLine();
// System.out.println(expressionStr);List<String> zx= toInfixExpression(expressionStr);List<String> rpn=parseSuffixExpression(zx);String rpnStr="";for(String str:rpn){rpnStr+=str;}System.out.println(rpnStr);System.out.println("计算结果:"+ calculate(rpn));}/*** 把字符串转换成中序表达式* @param s* @return*/public static List<String> toInfixExpression(String s) {List<String> ls = new ArrayList<String>();//存储中序表达式int i = 0;String str;char c;do {if ((c = s.charAt(i)) < 48 || (c = s.charAt(i)) > 57) {ls.add("" + c);i++;} else {str = "";while (i < s.length() && (c = s.charAt(i)) >= 48&& (c = s.charAt(i)) <= 57) {str += c;i++;}ls.add(str);}} while (i < s.length());return ls;}/*** 转换成逆波兰表达式* @param ls* @return*/public static List<String> parseSuffixExpression(List<String> ls) {Stack<String> s1=new Stack<String>();Stack<String> s2=new Stack<String>();List<String> lss = new ArrayList<String>();for (String ss : ls) {if (ss.matches("\\d+")) {lss.add(ss);} else if (ss.equals("(")) {s1.push(ss);} else if (ss.equals(")")) {while (!s1.peek().equals("(")) {lss.add(s1.pop());}s1.pop();} else {while (s1.size() != 0 && Operation.getValue(s1.peek()) >= Operation.getValue(ss)) {lss.add(s1.pop());}s1.push(ss);}}while (s1.size() != 0) {lss.add(s1.pop());}return lss;}/*** 通过逆波兰表达式计算结果* @param ls* @return*/public static int calculate(List<String> ls) {Stack<String> s=new Stack<String>();for (String str : ls) {if (str.matches("\\d+")) {s.push(str);} else {int b = Integer.parseInt(s.pop());int a = Integer.parseInt(s.pop());int result=0;if (str.equals("+")) {result = a + b;} else if (str.equals("-")) {result = a - b;} else if (str.equals("*")) {result = a * b;} else if (str.equals("\\")) {result = a / b;}s.push("" + result);}}System.out.println(s.peek());return Integer.parseInt(s.pop());}
}
参考https://www.cnblogs.com/chensongxian/p/7059802.html
中缀表达式、前缀表达式、后缀表达式相关推荐
- 中缀、前缀和后缀表达式
逆波兰表达式 先说一下中缀表达式,平时我们使用的运算表达式就是中缀表达式,例如1+3*2,中缀表达式的特点就是:二元运算符总是置于与之相关的两个运算对象之间 人读起来比较好理解,但是计算机处理起来就很 ...
- 中缀表达式转换为前缀及后缀表达式并求值【摘】
它们都是对表达式的记法,因此也被称为前缀记法.中缀记法和后缀记法.它们之间的区别在于运算符相对与操作数的位置不同:前缀表达式的运算符位于与其相关的操作数之前:中缀和后缀同理. 举例: (3 + 4) ...
- 中缀表达式转换为前缀或后缀表达式的手工做法
以 a/b + ( c*d - e*f) / g 为例: 步骤1:按照运算符的优先级对所有的运算单元加括号. ((a/b) + (( (c*d) - (e*f)) / g)) 步骤2:转换为前缀或后缀 ...
- c语言表达式的后缀,中缀表达式转换成后缀表达式C语言程序(一)
逆波兰表达式(Reverse Polish Notation)又叫后缀表达式.它是一种非常的表达式,可以将复杂的表达式转换成可以依靠简单的操作得到结果的表达.下面这段C语言即是用于实现将中缀表达式转换 ...
- 将中缀表达式转化为后缀表达式
我们把平时所用的标准四则运算表达式,即"9+(3-1)*3+10/2"叫做中缀表达式.因为所有的运算符号都在两数字的中间,现在我们的问题就是中缀到后缀的转化. 中缀表达式" ...
- NYOJ 257 中缀表达式表示成后缀表达式
话说这道题代码那个丑陋啊,,写出来我自己都不想再看第二遍啊...看了看聪神的代码,还消耗我3个NYOJ币啊,,更扯得是,聪神的代码我看不懂啊,,,,卧槽...这道题不再多说了,数据结构上有详细的介绍, ...
- 栈应用(中缀表达式转后缀表达式并计算后缀表达式的值)
[0]README 0.1) 本文旨在总结 中缀表达式转后缀表达式并计算后缀表达式的值 的步骤,并给出源代码实现: 0.2) 本文中涉及到的源代码均为原创,是对中缀转后缀和计算后缀的简单实现,(旨在理 ...
- 2015中缀表达式转化为后缀表达式(C++,附思路,注释多)
这篇文章默认你已经知道转换的原理了,所以就不介绍如何转换了~如果不知道的话可以看这两篇文章,写得很好,可以看懂~ 详解如何将中缀表达式转化为后缀表达式_Dacyuan的学习笔记-CSDN博客_中缀算式 ...
- 使用栈实现中缀表达式转换成后缀表达式并计算结果(逆波兰计算器)
一.中缀表达式转换成后缀表达式 具体步骤如下: 1.初始化栈stack(暂时存放运算符)以及集合list(存放后缀表达式) 2.从左向右扫描中缀表达式 3.当前元素为数字时,直接添加到list中 4. ...
- [python]将中缀表达式(infix)转换为后缀表达式(postfix)
将中缀表达式(infix)转换为后缀表达式(postfix) 算法描述 第一种情况,表达式不含括号. 假设存在一个函数prcd(op1,op2),其中op1和op2是两个操作符(在中缀表达式中,op1 ...
最新文章
- JQuery控制图片无缝滚动
- 【设计模式】软件设计七大原则 ( 合成复用原则 | 代码示例 )
- nginx搭建静态服务器(127.0.0.1/localhost访问)
- JavaFX 的 UI 控件集 ControlsFX
- java 和javafx_JavaFX 2 XYCharts和Java 7功能
- flutter不支持热更新_真当Flutter不能热更新?众能动态化Flutter
- ES6中的扩展运算符
- 先说一下JS的获取方法,其要比JQUERY的方法麻烦很多,后面以JQUERY的方法作对比。...
- 程序编译过程与软件启动过程
- iBatis 基础知识
- RS485通讯接口定义图详解
- 《随机过程》重点考点整理|复习笔记
- 如何使用计算机创电子表格,计算机如何创建表格?
- android高德地图点平滑移动,【高德地图SDK】如何实现轨迹平滑移动?
- oracle 支持ltfs的厂商_甲骨文革新磁带存储StorageTek产品线
- VM 将宿主机文件夹 映射至 虚拟机以及vm tools【共享文件夹、复制粘贴、拖动上传下载】
- 一对一直播源码、一对一聊天app源码前端后台功能说明
- 前端学习之浏览器缓存
- C# vb .net实现负片特效滤镜
- linux 内核 文件到磁盘影射
热门文章
- JavaScript 中的单例模式 (singleton in Javascript)
- ubuntu16.04 修改本机密码
- diskpart 设置硬盘格式
- qt动画实现抖动和下坠
- lvds输入悬空_LVDS的接口电路设计
- MATLAB 高等数学中的应用
- MFC Windows 程序设计(一)-程序员的解放
- c语言中文网pdf免费下载,C语言中文网VIP教程11.9.pdf
- AllyCAD v3.5 R12 1CD(专业CAD软件)
- unity如何做一个可以打开关闭的门?