原文在这里

表达式

前缀表达式(波兰表达式)

  1. 前缀表达式又称波兰式,前缀表达式的运算符位于操作数之前
  2. 举例说明: (3+4)×5-6 对应的前缀表达式就是 - × + 3 4 5 6

前缀表达式求值

前缀表达式的计算机求值

从右至左扫描表达式,遇到数字时,将数字压入堆栈,遇到运算符时,弹出栈顶的两个数,用运算符对它们做相应的计算(栈顶元素 和 次顶元素),并将结果入栈;重复上述过程直到表达式最左端,最后运算得出的值即为表达式的结果

例如: (3+4)×5-6 对应的前缀表达式就是 - × + 3 4 5 6 , 针对前缀表达式求值步骤如下:

  • 从右至左扫描,将6、5、4、3压入堆栈
  • 遇到+运算符,因此弹出34(3为栈顶元素,4为次顶元素),计算出3+4的值,得7,再将7入栈
  • 接下来是×运算符,因此弹出75,计算出7×5=35,将35入栈
  • 最后是-运算符,计算出35-6的值,即29,由此得出最终结果

中缀表达式

中缀表达式

中缀表达式就是常见的运算表达式,如(3+4)×5-6

中缀表达式的求值是我们人最熟悉的,但是对计算机来说却不好操作(前面我们讲的案例就能看的这个问题),因此,在计算结果时,往往会将中缀表达式转成其它表达式来操作(一般转成后缀表达式.)

中缀表达式对于我们人来好搞,计算机他算不算明白,就离谱

计算机不知道怎么算这个优先级

后缀表达式(逆波兰表达式)

后缀表达式

后缀表达式又称逆波兰表达式,与前缀表达式相似,只是运算符位于操作数之后

中举例说明: (3+4)×5-6 对应的后缀表达式就是 3 4 + 5 × 6 –

再比如:

正常的表达式 逆波兰表达式
a+b a b +
a+(b-c) a b c - +
a+(b-c)*d a b c – d * +
a+d*(b-c) a d b c - * +
a=1+3 a 1 3 + =

后缀表达式的计算机求值

从左至右扫描表达式,遇到数字时,将数字压入堆栈,遇到运算符时,弹出栈顶的两个数,用运算符对它们做相应的计算(次顶元素 和 栈顶元素),并将结果入栈;重复上述过程直到表达式最右端,最后运算得出的值即为表达式的结果

例如: (3+4)×5-6 对应的后缀表达式就是 3 4 + 5 × 6 - , 针对后缀表达式求值步骤如下:

  1. 从左至右扫描,将3和4压入堆栈;
  2. 遇到+运算符,因此弹出4和3(4为栈顶元素,3为次顶元素),计算出3+4的值,得7,再将7入栈;
  3. 将5入栈;
  4. 接下来是×运算符,因此弹出5和7,计算出7×5=35,将35入栈;
  5. 将6入栈;
  6. 最后是-运算符,计算出35-6的值,即29,由此得出最终结果

我们完成一个逆波兰计算器,要求完成如下任务:

  1. 输入一个逆波兰表达式(后缀表达式),使用栈(Stack), 计算其结果
  2. 支持小括号和多位数整数,因为这里我们主要讲的是数据结构,因此计算器进行简化,只支持对整数的计算。
  3. 思路分析
  4. 代码完成
package com.atguigu.stack;/*** ClassName:  <br/>* Description:  <br/>* Date: 2021-02-20 14:27 <br/>* @project data_algorithm* @package com.atguigu.stack*/import java.util.ArrayList;
import java.util.List;
import java.util.Stack;public class PolandNotation {}
//编写一个类 Operation 可以返回一个运算符 对应的优先级
class Operation {private static int ADD = 1;private static int SUB = 1;private static int MUL = 2;private static int DIV = 2;//写一个方法,返回对应的优先级数字public static int getValue(String operation) {int result = 0;switch (operation) {case "+":result = ADD;break;case "-":result = SUB;break;case "*":result = MUL;break;case "/":result = DIV;break;default:System.out.println("不存在该运算符" + operation);break;}return result;}}
//完成对逆波兰表达式的运算
/** 1)从左至右扫描,将3和4压入堆栈;2)遇到+运算符,因此弹出4和3(4为栈顶元素,3为次顶元素),计算出3+4的值,得7,再将7入栈;3)将5入栈;4)接下来是×运算符,因此弹出5和7,计算出7×5=35,将35入栈;5)将6入栈;6)最后是-运算符,计算出35-6的值,即29,由此得出最终结果*/public static int calculate(List<String> ls) {// 创建给栈, 只需要一个栈即可Stack<String> stack = new Stack<String>();// 遍历 lsfor (String item : ls) {// 这里使用正则表达式来取出数if (item.matches("\\d+")) { // 匹配的是多位数// 入栈stack.push(item);} else {// pop出两个数,并运算, 再入栈int num2 = Integer.parseInt(stack.pop());int num1 = Integer.parseInt(stack.pop());int res = 0;if (item.equals("+")) {res = num1 + num2;} else if (item.equals("-")) {res = num1 - num2;} else if (item.equals("*")) {res = num1 * num2;} else if (item.equals("/")) {res = num1 / num2;} else {throw new RuntimeException("运算符有误");}//把res 入栈stack.push("" + res);}}//最后留在stack中的数据是运算结果return Integer.parseInt(stack.pop());
}
//将一个逆波兰表达式, 依次将数据和运算符 放入到 ArrayList中
public static List<String> getListString(String suffixExpression) {//将 suffixExpression 分割String[] split = suffixExpression.split(" ");List<String> list = new ArrayList<String>();for(String ele: split) {list.add(ele);}return list;}
//方法:将 中缀表达式转成对应的List
//  s="1+((2+3)×4)-5";
public static List<String> toInfixExpressionList(String s) {//定义一个List,存放中缀表达式 对应的内容List<String> ls = new ArrayList<String>();int i = 0; //这时是一个指针,用于遍历 中缀表达式字符串String str; // 对多位数的拼接char c; // 每遍历到一个字符,就放入到cdo {//如果c是一个非数字,我需要加入到lsif((c=s.charAt(i)) < 48 ||  (c=s.charAt(i)) > 57) {ls.add("" + c);i++; //i需要后移} else { //如果是一个数,需要考虑多位数str = ""; //先将str 置成"" '0'[48]->'9'[57]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;//返回
}
//即 ArrayList [1,+,(,(,2,+,3,),*,4,),-,5]  =》 ArrayList [1,2,3,+,4,*,+,5,–]
//方法:将得到的中缀表达式对应的List => 后缀表达式对应的List
public static List<String> parseSuffixExpreesionList(List<String> ls) {//定义两个栈Stack<String> s1 = new Stack<String>(); // 符号栈//说明:因为s2 这个栈,在整个转换过程中,没有pop操作,而且后面我们还需要逆序输出//因此比较麻烦,这里我们就不用 Stack<String> 直接使用 List<String> s2//Stack<String> s2 = new Stack<String>(); // 储存中间结果的栈s2List<String> s2 = new ArrayList<String>(); // 储存中间结果的Lists2//遍历lsfor(String item: ls) {//如果是一个数,加入s2if(item.matches("\\d+")) {s2.add(item);} else if (item.equals("(")) {s1.push(item);} else if (item.equals(")")) {//如果是右括号“)”,则依次弹出s1栈顶的运算符,并压入s2,直到遇到左括号为止,此时将这一对括号丢弃while(!s1.peek().equals("(")) {s2.add(s1.pop());}s1.pop();//!!! 将 ( 弹出 s1栈, 消除小括号} else {//当item的优先级小于等于s1栈顶运算符, 将s1栈顶的运算符弹出并加入到s2中,再次转到(4.1)与s1中新的栈顶运算符相比较//问题:我们缺少一个比较优先级高低的方法while(s1.size() != 0 && Operation.getValue(s1.peek()) >= Operation.getValue(item) ) {s2.add(s1.pop());}//还需要将item压入栈s1.push(item);}}//将s1中剩余的运算符依次弹出并加入s2while(s1.size() != 0) {s2.add(s1.pop());}return s2; //注意因为是存放到List, 因此按顺序输出就是对应的后缀表达式对应的List}

执行

public static void main(String[] args) {//完成将一个中缀表达式转成后缀表达式的功能//说明//1. 1+((2+3)×4)-5 => 转成  1 2 3 + 4 × + 5 –//2. 因为直接对str 进行操作,不方便,因此 先将  "1+((2+3)×4)-5" =》 中缀的表达式对应的List//   即 "1+((2+3)×4)-5" => ArrayList [1,+,(,(,2,+,3,),*,4,),-,5]//3. 将得到的中缀表达式对应的List => 后缀表达式对应的List//   即 ArrayList [1,+,(,(,2,+,3,),*,4,),-,5]  =》 ArrayList [1,2,3,+,4,*,+,5,–]String expression = "1+((2+3)*4)-5";//注意表达式List<String> infixExpressionList = toInfixExpressionList(expression);System.out.println("中缀表达式对应的List=" + infixExpressionList); // ArrayList [1,+,(,(,2,+,3,),*,4,),-,5]List<String> suffixExpreesionList = parseSuffixExpreesionList(infixExpressionList);System.out.println("后缀表达式对应的List" + suffixExpreesionList); //ArrayList [1,2,3,+,4,*,+,5,–]System.out.printf("expression=%d", calculate(suffixExpreesionList)); // ?/*//先定义给逆波兰表达式//(30+4)×5-6  => 30 4 + 5 × 6 - => 164// 4 * 5 - 8 + 60 + 8 / 2 => 4 5 * 8 - 60 + 8 2 / +//测试//说明为了方便,逆波兰表达式 的数字和符号使用空格隔开//String suffixExpression = "30 4 + 5 * 6 -";String suffixExpression = "4 5 * 8 - 60 + 8 2 / +"; // 76//思路//1. 先将 "3 4 + 5 × 6 - " => 放到ArrayList中//2. 将 ArrayList 传递给一个方法,遍历 ArrayList 配合栈 完成计算List<String> list = getListString(suffixExpression);System.out.println("rpnList=" + list);int res = calculate(list);System.out.println("计算的结果是=" + res);*/
}

原文在这里

前缀中缀后缀表达式的计算求值相关推荐

  1. C语言实现中缀转后缀表达式,并求值

    C语言实现中缀转后缀表达式,并求值 #include <stdio.h> #include <stdlib.h> #include <ctype.h> #inclu ...

  2. 数据结构:前缀,中缀,后缀表达式(逆波兰表达式)

    前缀表达式(波兰表达式) 前缀表达式的运算符位于操作数之前. 比如 (1+2)*3-4  对应的前缀表达式就是: - * + 1 2 3 4 前缀表达式的计算机求值 从右至左扫描表达式,遇到数字时,就 ...

  3. 前缀中缀后缀表达式介绍

    一 前缀表达式 1 前缀表达式又称波兰式,前缀表达式的运算符位于操作数之前. 2 举例 (3+4)×5-6 对应的前缀表达式是: - × + 3 4 5 6 3 前缀表达式的计算机求值过程 从右至左扫 ...

  4. 阿龙学堂-中缀-后缀表达式的计算

    1.简介 在数据结构中,有一种数据结构叫做:Stack,LIFO(Last In First Out),在这个结构中,有个后缀表达式计算,运用该数据结构进行计算. 栈是一种只允许一端操作的线性数据结构 ...

  5. 前缀 中缀 后缀表达式

    1.前缀表达式叫波兰式,后缀叫逆波兰式 2.中缀表达式转另外两个比较简单,前后缀装中缀较麻烦 3.问题分求表达式还是求值,如果是求值则需要两个栈,一个是操作符栈,一个是操作数栈,等操作符栈入栈完毕后依 ...

  6. 前缀 中缀 后缀表达式2

    对于未经训练的用户来说,计算机科学领域中数学表达式求值的传统方法即不顺手又难以使用:软件工程师 Nikola.Stepan 旨在改变这些传统方法.他的 applet W3Eval 对表达式求值与您用纸 ...

  7. 表达式树前缀中缀后缀表达式

    表达式树( expression tree ), 表达式树的树叶是操作数( operand ),比如常数或变量,而其他的节点为操作符( operator )如: 由于这里所有的操作都是二元的,因此这棵 ...

  8. python【数据结构与算法】表达式(前缀中缀后缀表达式)与Two fork tree

    文章目录 1 相关概念 2 与二叉树关系 3 表达式转换 4 另一种方法 1 相关概念 前缀表达式(Prefix Notation)是指将运算符写在前面操作数写在后面的不包含括号的表达式,而且为了纪念 ...

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

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

最新文章

  1. ASP.Net 获取当前时间
  2. Nginx log error:client sent invalid userid cookie
  3. C语言斐波那契数列(附完整源码)
  4. 【Linux】一步一步学Linux——dpkg-statoverride命令(277)
  5. Windows 10 IoT Core 17101 for Insider 版本更新
  6. Android开发:调用camera API 创建MediaRecorder
  7. js操作select标签
  8. 华为P30现身华为新加坡官网:坐实水滴屏
  9. Hibernate的查询 HQL查询 查询某几列
  10. Audio PCM输出流程(三十三)
  11. mysql oldaltertable_MySQL5.6 ALTER TABLE 分析和测试
  12. 一文了解几十万年的科技史
  13. 基于Go语言Echo+Layui的OA办公系统
  14. 《西安女娃》——黑撒
  15. 损失函数--持续更新
  16. 视频工厂分享vlog拍摄技巧
  17. 电脑超时空保卫者——光华反病毒软件(转)
  18. 505 新国王游戏 思维 [代码源][namomo spring camp]每日一题div2
  19. Mac?Windows?游戏本?大学生到底该如何选择适合自己的笔记本
  20. 【计算机网络】——计算机网络基础

热门文章

  1. AMD 5XXX 系列显卡的 peak bandwidth计算
  2. 管理飞扬跋扈的技术部
  3. C/C++拾遗录--关于一个C语言小程序的分析
  4. DCT原型 ——傅里叶级数
  5. 麻雀虽小,五脏俱全:分析CVS活动情况的小工具(有源码供学习)
  6. linux jps 命令
  7. you need to resolve your current index first 解决办法
  8. 精读《V8 引擎 Lazy Parsing》
  9. 前端布局神器display:flex
  10. cocos2d-lua3.7组件篇(三)-http通信demo