前缀、中缀、后缀表达式及其相互转化的Java实现
(1) 初始化两个栈:运算符栈S1和储存中间结果的栈S2;
(2) 从右至左扫描中缀表达式;
(3) 遇到操作数时,将其压入S2;
(4) 遇到运算符时,比较其与S1栈顶运算符的优先级:
(4-1) 如果S1为空,或栈顶运算符为右括号“)”,则直接将此运算符入栈;
(4-2) 否则,若优先级比栈顶运算符的较高或相等,也将运算符压入S1;
(4-3) 否则,将S1栈顶的运算符弹出并压入到S2中,再次转到(4-1)与S1中新的栈顶运算符相比较;
(5) 遇到括号时:
(5-1) 如果是右括号“)”,则直接压入S1;
(5-2) 如果是左括号“(”,则依次弹出S1栈顶的运算符,并压入S2,直到遇到右括号为止,此时将这一对括号丢弃;
(6) 重复步骤(2)至(5),直到表达式的最左边;
(7) 将S1中剩余的运算符依次弹出并压入S2;
(8) 依次弹出S2中的元素并输出,结果即为中缀表达式对应的前缀表达式。
例如,将中缀表达式“1+((2+3)×4)-5”转换为前缀表达式的过程如下:
扫描到的元素 | S2(栈底->栈顶) | S1 (栈底->栈顶) | 说明 |
5 | 5 | 空 | 数字,直接入栈 |
- | 5 | - | S1为空,运算符直接入栈 |
) | 5 | - ) | 右括号直接入栈 |
4 | 5 4 | - ) | 数字直接入栈 |
× | 5 4 | - ) × | S1栈顶是右括号,直接入栈 |
) | 5 4 | - ) × ) | 右括号直接入栈 |
3 | 5 4 3 | - ) × ) | 数字 |
+ | 5 4 3 | - ) × ) + | S1栈顶是右括号,直接入栈 |
2 | 5 4 3 2 | - ) × ) + | 数字 |
( | 5 4 3 2 + | - ) × | 左括号,弹出运算符直至遇到右括号 |
( | 5 4 3 2 + × | - | 同上 |
+ | 5 4 3 2 + × | - + | 优先级与-相同,入栈 |
1 | 5 4 3 2 + × 1 | - + | 数字 |
到达最左端 | 5 4 3 2 + × 1 + - | 空 | S1中剩余的运算符 |
因此结果为“- + 1 × + 2 3 4 5”。
(1) 初始化两个栈:运算符栈S1和储存中间结果的栈S2;
(2) 从左至右扫描中缀表达式;
(3) 遇到操作数时,将其压入S2;
(4) 遇到运算符时,比较其与S1栈顶运算符的优先级:
(4-1) 如果S1为空,或栈顶运算符为左括号“(”,则直接将此运算符入栈;
(4-2) 否则,若优先级比栈顶运算符的高,也将运算符压入S1(注意转换为前缀表达式时是优先级较高或相同,而这里则不包括相同的情况);
(4-3) 否则,将S1栈顶的运算符弹出并压入到S2中,再次转到(4-1)与S1中新的栈顶运算符相比较;
(5) 遇到括号时:
(5-1) 如果是左括号“(”,则直接压入S1;
(5-2) 如果是右括号“)”,则依次弹出S1栈顶的运算符,并压入S2,直到遇到左括号为止,此时将这一对括号丢弃;
(6) 重复步骤(2)至(5),直到表达式的最右边;
(7) 将S1中剩余的运算符依次弹出并压入S2;
(8) 依次弹出S2中的元素并输出,结果的逆序即为中缀表达式对应的后缀表达式(转换为前缀表达式时不用逆序)。
扫描到的元素 | S2(栈底->栈顶) | S1 (栈底->栈顶) | 说明 |
1 | 1 | 空 | 数字,直接入栈 |
+ | 1 | + | S1为空,运算符直接入栈 |
( | 1 | + ( | 左括号,直接入栈 |
( | 1 | + ( ( | 同上 |
2 | 1 2 | + ( ( | 数字 |
+ | 1 2 | + ( ( + | S1栈顶为左括号,运算符直接入栈 |
3 | 1 2 3 | + ( ( + | 数字 |
) | 1 2 3 + | + ( | 右括号,弹出运算符直至遇到左括号 |
× | 1 2 3 + | + ( × | S1栈顶为左括号,运算符直接入栈 |
4 | 1 2 3 + 4 | + ( × | 数字 |
) | 1 2 3 + 4 × | + | 右括号,弹出运算符直至遇到左括号 |
- | 1 2 3 + 4 × + | - | -与+优先级相同,因此弹出+,再压入- |
5 | 1 2 3 + 4 × + 5 | - | 数字 |
到达最右端 | 1 2 3 + 4 × + 5 - | 空 | S1中剩余的运算符 |
String midToPost(String midSeq){Stack<Character> S1 = new Stack<Character>();Stack<Character> S2 = new Stack<Character>();int len = midSeq.length();int index = 0;while(index < len){char c = midSeq.charAt(index);switch(c){case '(':S1.push(c);break;case ')':while(S1.peek() != '(')S2.push(S1.pop());S1.pop();break;case '+':case '-':while(!S1.empty() && S1.peek() != '(')S2.push(S1.pop());S1.push(c);break;case '*':case '/':while(!S1.empty() && S1.peek().toString().matches("[*/]"))S2.push(S1.pop());S1.push(c);break;default:S2.push(c);}index++;}while(!S1.empty())S2.push(S1.pop());Iterator<Character> iter = S2.iterator();StringBuffer postSeq = new StringBuffer();while(iter.hasNext())postSeq.append(iter.next());return postSeq.toString();
}String midToPre(String midSeq){Stack<Character> S1 = new Stack<>(); //S1用来存放临时运算符Stack<Character> S2 = new Stack<Character>(); //S2用来存放最后结果int len = midSeq.length();int index = len - 1;while(index >= 0){char c = midSeq.charAt(index);switch(c){case ')':S1.push(c);break;case '(':while(S1.peek() != ')'){S2.push(S1.pop());}S1.pop();break;case '*':case '/':S1.push(c);break;case '+':case '-':if(S1.empty() || S1.peek().toString().matches("[+-]"))S1.push(c);else{while(!S1.empty() && S1.peek().toString().matches("[*/]")){S2.push(S1.pop());}S1.push(c);}break;default:S2.push(c);}index--;}while(!S1.empty())S2.push(S1.pop());StringBuffer preSeq = new StringBuffer();Iterator<Character> iter = S2.iterator();while(iter.hasNext())preSeq.append(iter.next());preSeq = preSeq.reverse();return preSeq.toString();
}
前缀、中缀、后缀表达式及其相互转化的Java实现相关推荐
- 前缀中缀后缀表达式的计算求值
原文在这里 表达式 前缀表达式(波兰表达式) 前缀表达式又称波兰式,前缀表达式的运算符位于操作数之前 举例说明: (3+4)×5-6 对应的前缀表达式就是 - × + 3 4 5 6 前缀表达式求值 ...
- 前缀 中缀 后缀表达式2
对于未经训练的用户来说,计算机科学领域中数学表达式求值的传统方法即不顺手又难以使用:软件工程师 Nikola.Stepan 旨在改变这些传统方法.他的 applet W3Eval 对表达式求值与您用纸 ...
- python【数据结构与算法】表达式(前缀中缀后缀表达式)与Two fork tree
文章目录 1 相关概念 2 与二叉树关系 3 表达式转换 4 另一种方法 1 相关概念 前缀表达式(Prefix Notation)是指将运算符写在前面操作数写在后面的不包含括号的表达式,而且为了纪念 ...
- 数据结构:前缀,中缀,后缀表达式(逆波兰表达式)
前缀表达式(波兰表达式) 前缀表达式的运算符位于操作数之前. 比如 (1+2)*3-4 对应的前缀表达式就是: - * + 1 2 3 4 前缀表达式的计算机求值 从右至左扫描表达式,遇到数字时,就 ...
- 表达式树前缀中缀后缀表达式
表达式树( expression tree ), 表达式树的树叶是操作数( operand ),比如常数或变量,而其他的节点为操作符( operator )如: 由于这里所有的操作都是二元的,因此这棵 ...
- 前缀中缀后缀表达式介绍
一 前缀表达式 1 前缀表达式又称波兰式,前缀表达式的运算符位于操作数之前. 2 举例 (3+4)×5-6 对应的前缀表达式是: - × + 3 4 5 6 3 前缀表达式的计算机求值过程 从右至左扫 ...
- 前缀 中缀 后缀表达式
1.前缀表达式叫波兰式,后缀叫逆波兰式 2.中缀表达式转另外两个比较简单,前后缀装中缀较麻烦 3.问题分求表达式还是求值,如果是求值则需要两个栈,一个是操作符栈,一个是操作数栈,等操作符栈入栈完毕后依 ...
- C#数据结构-前缀中缀后缀+中缀转后缀
目录 一.前缀中缀后缀表达式 1.中缀表达式 2.前缀表达式 3.后缀表达式 二.中缀转后缀 一.前缀中缀后缀表达式 1.中缀表达式 中缀表达式就是平常生活中计算式子的写法,例如:(3+4)*5-6 ...
- 中缀表达式转换为前缀及后缀表达式并求值【摘】
它们都是对表达式的记法,因此也被称为前缀记法.中缀记法和后缀记法.它们之间的区别在于运算符相对与操作数的位置不同:前缀表达式的运算符位于与其相关的操作数之前:中缀和后缀同理. 举例: (3 + 4) ...
最新文章
- float占几个字节_一个HashMap对象占多少字节?
- 知识图谱(知识图谱构建)
- mysql 常用配置_mysql 常用配置
- java7 AIO初体验
- form 窗体增加边框_C#控件美化之路(13):美化Form窗口(上)
- 7.python实现高效端口扫描器之nmap模块
- 【movable-area、movable-view】 可移动区域组件说明
- 我理解设计模式C++实现观察者模式Observer Pattern
- python rabitmq_3、Python结合RabbitMQ实现消息传递
- java中插入表格_java 集成 pageoffice 实现在 word 中插入表格并赋值
- mysql 函数无法访问_mysql 中出现:不能打开到主机的连接,在端口3306: 连接失败...
- Google 推出的编程学习应用 Grasshopper
- Android手机网页字体异常,移动端html5手机网站的中文字体使用
- 深入机械制造业供应链关键节点,SCM供应链管理系统全面防控企业供应链风险
- ICMP协议与ping
- java根据银行卡前几位判断所属银行,个别银行可自定义,如最后的长沙银行
- go语言和c运行效率,Go语言执行效率
- 【MySQL数据库】 - 复杂查询(二)
- 【MySQL】MySQL之权限管理
- c语言 验证用户名密码
热门文章
- 百度高德位置定位服务器,调用百度、高德地图App,百度地图网页版,App定位
- dev里timeedit控件如何赋值_抽奖程序里的字节跳动模式和时长控制,让抽奖更有仪式感!...
- linux工科软件,linux基础网络工具学习笔记
- python zipfile教程_Python模块zipfile原理及使用方法详解
- ue4场景没阴影_UE4 Mobile使用动态阴影的一些小结
- win2003服务器的一些安全设置
- Windows服务器下升级PHP版本的方法
- iis配置绑定二级域名的问题
- 使用IDEA整合spring4+spring mvc+hibernate
- 递归方法:对于树形结构的表,根据当前数据获取无限极的父级名称