中缀 转 后缀 实现计算
文章目录
- 前言
- 一、后缀表达式
- 二、中缀转后缀 方式
- 三、中缀 转 后缀 并计算 实现
- 四、总结
前言
中缀表达式就是我们在进行加减乘除时经常使用的表达式,后缀表达式是对计算机友好的表达式,计算机可以利用两个栈来实现输入的计算字符串的计算工作
提示:以下是本篇文章正文内容,下面案例可供参考
一、后缀表达式
后缀表达式也叫逆波兰式,实现逆波兰式的算法,难度并不大,但为什么要将看似简单的中缀表达式转换为复杂的逆波兰式?原因就在于这个简单是相对人类的思维结构来说的,对计算机而言中序表达式是非常复杂的结构。相对的,逆波兰式在计算机看来却是比较简单易懂的结构。因为计算机普遍采用的内存结构是栈式结构,它执行先进后出的顺序。
(a+b)c-(a+b)/e的后缀表达式为:ab+cab+e/-
二、中缀转后缀 方式
首先需要分配2个栈,一个作为临时存储运算符的栈S1(含一个结束符号),一个作为存放结果(逆波兰式)的栈S2(空栈),S1栈可先放入优先级最低的运算符#,注意,中缀式应以此最低优先级的运算符结束。可指定其他字符,不一定非#不可。从中缀式的左端开始取字符,逐序进行如下步骤:
- 若取出的字符是操作数,则分析出完整的运算数,该操作数直接送入S2栈。
- 若取出的字符是运算符,则将该运算符与S1栈栈顶元素比较,如果该运算符(不包括括号运算符)优先级高于S1栈栈顶运算符(包括左括号)优先级,则将该运算符进S1栈,否则,将S1栈的栈顶运算符弹出,送入S2栈中,直至S1栈栈顶运算符(包括左括号)低于(不包括等于)该运算符优先级时停止弹出运算符,最后将该运算符送入S1栈。
- 若取出的字符是“(”,则直接送入S1栈顶。
- 若取出的字符是“)”,则将距离S1栈栈顶最近的“(”之间的运算符,逐个出栈,依次送入S2栈,此时抛弃“(”。
- 重复上面的1~4步,直至处理完所有的输入字符。
- 若取出的字符是“#”,则将S1栈内所有运算符(不包括“#”),逐个出栈,依次送入S2栈。
计算示例
三、中缀 转 后缀 并计算 实现
public class testPolan {public static void main(String[] args) {String exp = "1+((12+0)*4)-5";List<String> infixExpressionList = toInfixExpressionList(exp);List<String> suffixExpressionList = parseSuffixExpressionList(infixExpressionList);System.out.println("后缀List" + suffixExpressionList);System.out.printf(exp + " = " + calculate(suffixExpressionList));}//方法:将中缀转后缀public static List<String> parseSuffixExpressionList(List<String> ls) {//定义两个栈Stack<String> s1 = new Stack<String>();//符号栈//因为s2这个栈没有pop,后面还要逆序输出//因此比较麻烦,我们直接使用List2List<String> s2 = new ArrayList<String>();//遍历lsfor (String item : ls) {//如果是一个数就加入s2if (item.matches("\\d+")) {s2.add(item);} else if (item.equals("(")) {s1.push(item);} else if (item.equals(")")) {while (!s1.peek().equals("(")) {s2.add(s1.pop());}s1.pop();//将小括号弹出} else {//item的运算符优先级小于等于栈顶//缺少优先级方法,见下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;}//方法:将中缀表达式转成对应的Listpublic static List<String> toInfixExpressionList(String s) {//先定义一个list存放中缀表达式对应的数据List<String> ls = new ArrayList<String>();int i = 0;//这是一个指针,用于遍历中缀表达式字符串String str;//多位数的拼接char c;//每遍历一个字符就放到c中do {//如果c是非数字,我们就加到lsif ((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;}//从左往右扫描表达式,遇到数字时,将数字压入堆栈//遇到运算符时,弹出栈顶的两个数,计算//注意顺序:次顶元素 -处理->栈顶元素//并将结果入栈,重复上述过程直到表达式最右端//最后结果即为计算结果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 {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("错误");}stack.push(res + "");}}return Integer.parseInt(stack.pop());}//类:返回优先级数字static 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 oper) {int result = 0;switch (oper) {case "+":result = ADD;break;case "-":result = SUB;break;case "*":result = MUL;break;case "/":result = DIV;default:
// System.out.println("无法解析");break;}return result;}}}
四、总结
加油噢!
中缀 转 后缀 实现计算相关推荐
- 数据结构之栈实现中缀转后缀并计算结果
一.中缀变后缀过程分析 给定一个中缀,最后变为后缀的过程其实并不算复杂,下面分析一下过程: 1. 首先面对一个中缀表达式,我们需要两个栈,一个用来存放运算符,即符号栈 operatorstack,一个 ...
- C语言实现中缀转后缀并计算表达式结果
文章目录 一.问题描述 二.AC代码 三.注意点 四.实现思路/代码解析 一.问题描述 [问题描述] 从标准输入中读入一个整数算术运算表达式,如5 - 1 * 2 * 3 + 12 / 2 / 2 ...
- java简易计算机(用栈实现中缀转后缀,计算后缀表达式)
这学期java课的一个小作业,用java编一个小计算器. 个人认为要点在于: 1.计算机的布局,即按钮和输出框的布局需要知道怎么操作,按钮的大小和字体的大小颜色.不同布局中按钮的改变大小等等 2.用栈 ...
- java 中缀转后缀并计算_Java实现表达式计算(中缀转后缀)
定义: 中缀表达式:我们平时写的数学表达式一般为中缀表达式,如"5+2*(3*(3-1*2+1))",直接拿中缀表达式直接让计算机计算表达式的结果并不能做到. 后缀表达式:把中缀表 ...
- 顺序栈计算器 中缀转后缀表达式
顺序栈计算器 中缀转后缀表达式 前言 一.后缀表达式简述 二.参考书目中的函数实现 1.输入一个后缀表达式并计算 2.将中缀转后缀表达式 三.在原方法基础上改写并结合两个方法 1.输入一个后缀表达式并 ...
- 前缀、中缀和后缀表达式详解,中缀表达式到后缀表达式的转换规则,以及后缀表达式的计算规则,附计算代码
1. 中缀.前缀和后缀表达式 1.1 中缀表达式 首先,中缀表达式的这个"缀"指运算符在两个操作数的位置.中缀表达式其实就是我们常用的算术表达式,比如 2 + 9 - (32 * ...
- 中缀表达式计算、后缀表达式计算、中缀转后缀
代码来源 : bilibili网站 :https://www.bilibili.com/video/av91996256?from=search&seid=174497233083020298 ...
- 中缀转后缀表达式并计算
注:本博客是基于<数据结构>这门课,主要是为了自己考研,准备专业课 图解转自:中缀转后缀算法 中缀转后缀算法 中缀表达式转后缀表达式遵循以下原则: 遇到操作数,直接输出 当栈为空时,若遇到 ...
- 中缀转后缀并分别计算
参考了几篇大佬的文章最后写出,通过Android studio实现. 只实现个位整数+-*/,如有更多需求,请自行修改. Cal(中缀转后缀) public class Cal {LinkedList ...
最新文章
- 怎样去判断一个网站是不是伪静态网站
- java多个数求和_Java:多个数求和
- Spring4学习笔记
- 75. CPU 100%运行实战案例分析
- 转jmeter --JDBC请求
- 写一个sql实现以下查询结果_书写高质量SQL的30条建议
- 基于C#.NET的--Windows进程管理工具
- 华三 h3c vrrp和监视端口配置
- phpstudy没有安装VC11、VC14运行库
- 微软私有云资源链接总结分享
- LaTeX代码: 下划线与删除线 ← 利用 ulem 宏包
- matlab费曼编码输入,多点格林函数数值积分(费曼参数积分)的程序分析及应用
- 混合高斯背景建模原理
- 联机系统的服务器,远程联机服务器系统
- [循证理论与实践] Meta分析系列之五:贝叶斯 Meta 分析与 WinBUGS 软件
- 38、Java——汽车租赁系统(JDBC+MySQL+Apache DBUtils)
- 交易委托账本 order book
- oracle报错1034,oracle数据库登陆报错ora-1034
- 怎么对比两个mysql数据库_[实战]如何对比两个数据库之间的变化
- 如何区分嵌入式系统和嵌入式操作系统