中缀表达式、前缀表达式、后缀表达式

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. 中缀、前缀和后缀表达式

    逆波兰表达式 先说一下中缀表达式,平时我们使用的运算表达式就是中缀表达式,例如1+3*2,中缀表达式的特点就是:二元运算符总是置于与之相关的两个运算对象之间 人读起来比较好理解,但是计算机处理起来就很 ...

  2. 中缀表达式转换为前缀及后缀表达式并求值【摘】

    它们都是对表达式的记法,因此也被称为前缀记法.中缀记法和后缀记法.它们之间的区别在于运算符相对与操作数的位置不同:前缀表达式的运算符位于与其相关的操作数之前:中缀和后缀同理. 举例: (3 + 4) ...

  3. 中缀表达式转换为前缀或后缀表达式的手工做法

    以 a/b + ( c*d - e*f) / g 为例: 步骤1:按照运算符的优先级对所有的运算单元加括号. ((a/b) + (( (c*d) - (e*f)) / g)) 步骤2:转换为前缀或后缀 ...

  4. c语言表达式的后缀,中缀表达式转换成后缀表达式C语言程序(一)

    逆波兰表达式(Reverse Polish Notation)又叫后缀表达式.它是一种非常的表达式,可以将复杂的表达式转换成可以依靠简单的操作得到结果的表达.下面这段C语言即是用于实现将中缀表达式转换 ...

  5. 将中缀表达式转化为后缀表达式

    我们把平时所用的标准四则运算表达式,即"9+(3-1)*3+10/2"叫做中缀表达式.因为所有的运算符号都在两数字的中间,现在我们的问题就是中缀到后缀的转化. 中缀表达式" ...

  6. NYOJ 257 中缀表达式表示成后缀表达式

    话说这道题代码那个丑陋啊,,写出来我自己都不想再看第二遍啊...看了看聪神的代码,还消耗我3个NYOJ币啊,,更扯得是,聪神的代码我看不懂啊,,,,卧槽...这道题不再多说了,数据结构上有详细的介绍, ...

  7. 栈应用(中缀表达式转后缀表达式并计算后缀表达式的值)

    [0]README 0.1) 本文旨在总结 中缀表达式转后缀表达式并计算后缀表达式的值 的步骤,并给出源代码实现: 0.2) 本文中涉及到的源代码均为原创,是对中缀转后缀和计算后缀的简单实现,(旨在理 ...

  8. 2015中缀表达式转化为后缀表达式(C++,附思路,注释多)

    这篇文章默认你已经知道转换的原理了,所以就不介绍如何转换了~如果不知道的话可以看这两篇文章,写得很好,可以看懂~ 详解如何将中缀表达式转化为后缀表达式_Dacyuan的学习笔记-CSDN博客_中缀算式 ...

  9. 使用栈实现中缀表达式转换成后缀表达式并计算结果(逆波兰计算器)

    一.中缀表达式转换成后缀表达式 具体步骤如下: 1.初始化栈stack(暂时存放运算符)以及集合list(存放后缀表达式) 2.从左向右扫描中缀表达式 3.当前元素为数字时,直接添加到list中 4. ...

  10. [python]将中缀表达式(infix)转换为后缀表达式(postfix)

    将中缀表达式(infix)转换为后缀表达式(postfix) 算法描述 第一种情况,表达式不含括号. 假设存在一个函数prcd(op1,op2),其中op1和op2是两个操作符(在中缀表达式中,op1 ...

最新文章

  1. JQuery控制图片无缝滚动
  2. 【设计模式】软件设计七大原则 ( 合成复用原则 | 代码示例 )
  3. nginx搭建静态服务器(127.0.0.1/localhost访问)
  4. JavaFX 的 UI 控件集 ControlsFX
  5. java 和javafx_JavaFX 2 XYCharts和Java 7功能
  6. flutter不支持热更新_真当Flutter不能热更新?众能动态化Flutter
  7. ES6中的扩展运算符
  8. 先说一下JS的获取方法,其要比JQUERY的方法麻烦很多,后面以JQUERY的方法作对比。...
  9. 程序编译过程与软件启动过程
  10. iBatis 基础知识
  11. RS485通讯接口定义图详解
  12. 《随机过程》重点考点整理|复习笔记
  13. 如何使用计算机创电子表格,计算机如何创建表格?
  14. android高德地图点平滑移动,【高德地图SDK】如何实现轨迹平滑移动?
  15. oracle 支持ltfs的厂商_甲骨文革新磁带存储StorageTek产品线
  16. VM 将宿主机文件夹 映射至 虚拟机以及vm tools【共享文件夹、复制粘贴、拖动上传下载】
  17. 一对一直播源码、一对一聊天app源码前端后台功能说明
  18. 前端学习之浏览器缓存
  19. C# vb .net实现负片特效滤镜
  20. linux 内核 文件到磁盘影射

热门文章

  1. JavaScript 中的单例模式 (singleton in Javascript)
  2. ubuntu16.04 修改本机密码
  3. diskpart 设置硬盘格式
  4. qt动画实现抖动和下坠
  5. lvds输入悬空_LVDS的接口电路设计
  6. MATLAB 高等数学中的应用
  7. MFC Windows 程序设计(一)-程序员的解放
  8. c语言中文网pdf免费下载,C语言中文网VIP教程11.9.pdf
  9. AllyCAD v3.5 R12 1CD(专业CAD软件)
  10. unity如何做一个可以打开关闭的门?