[Java]将算术表达式(中序表达式Infix)转成后续表达式Postfix
Inlet类:
package com.hy;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
// 此类用于把算术表达式送入解析器
public class Inlet {
public static void main(String[] args) throws IOException{
// 取得用户输入的表达式
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String rawExpression = null;
System.out.print("请输入算术表达式:");
rawExpression = br.readLine();
// 得到合法的算术表达式
String expression="";
for(int i=0;i<rawExpression.length();i++){
// 拿到表达式的每个字符
char c=rawExpression.charAt(i);
//System.out.print(c+",");
if(Character.isDigit(c) || c=='+' || c=='-' || c=='*' || c=='/' || c=='(' || c==')' ){
//System.out.print(c);
expression+=c;
}else{
System.out.print(" "+c+"不是合法的算术表达式字符.");
System.exit(0);
}
}
// 送去解析
Parser p=new Parser(expression);
//p.print();
// 转为后序表达式
Trans t=new Trans(p.getList());
t.print();
}
}
Parser类:
package com.hy;
import java.util.ArrayList;
import java.util.List;
// 此类用于将算术表达式解析成包含操作数和操作符的链表
public class Parser {
private List<String> list;// 用于存储表达式的链表
public List<String> getList() {
return list;
}
public Parser(String expression){
list=new ArrayList<String>();
String str="";
for(int i=0;i<expression.length();i++){
char c=expression.charAt(i);
if(Character.isDigit(c)){
str+=c;
}else{
if(str.length()>0){// 此判断是因为有+(这种符号相连的情况
//System.out.println(str);
list.add(str);
str="";
}
//System.out.println(c);
list.add(String.valueOf(c));
}
}
if(str.length()>0){// 此判断是因为可能表达式不是以=结尾
//System.out.println(str);
list.add(str);
str="";
}
}
public void print(){
for(String str:list){
System.out.println(str);
}
}
}
Trans类:
package com.hy;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
// 此类用于将中序表达式转译成后序表达式
public class Trans {
private Stack<String> stack;// 用于存储操作符的栈
private List<String> postfixList;// 用于存储后序表达式的链表
public Trans(List<String> list){
stack=new Stack<String>();
postfixList=new ArrayList<String>();
for(String str:list){
// 这个分支是当前项是操作符号的情况
if(str.equals("+") || str.equals("-") || str.equals("*") || str.equals("/") || str.equals("(") || str.equals(")") ){
String opThis=str;
if(stack.size()==0){
// 如果栈为空,直接把操作符推入栈
stack.push(opThis);
}else if(str.equals("(")){
// 如果操作符是左括号,直接推入栈
stack.push(opThis);
}else if(str.equals(")")){
// 如果操作符是右括号,则往前找左括号,将左括号之后的操作符放到后续表达式列表中
while(stack.peek().equals("(")==false){ // stack.peek()是取栈顶元素而不弹出
postfixList.add(stack.pop());
}
stack.pop();// 左括号丢弃,由此完成了去括号的过程
}else{
// 看栈顶元素,如果它优先级大于等于当前操作符的优先级,则弹出放到后续表达式列表中
while( stack.size()>0 && (getOpLevel(stack.peek())>=getOpLevel(opThis)) ){
postfixList.add(stack.pop());
}
stack.push(opThis);// 当前操作符入栈
}
}else{
// 这个分支是当前项是操作数的情况
postfixList.add(str);// 操作数直接入栈
}
}
// 将栈中余下的操作符弹出放到后续表达式列表中
while(stack.size()>0){
String opTop=stack.pop();
postfixList.add(opTop);
}
}
// 取得操作符的等级
private int getOpLevel(String op){
if(op.equals("+") || op.equals("-") ){
return 0;
}else if(op.equals("*") || op.equals("/") ){
return 1;
}
return -1;
}
public void print(){
for(String str:postfixList){
System.out.print(str);
}
}
}
执行结果:
请输入算术表达式:1+2-3 12+3- 请输入算术表达式:1+2*3 123*+ 请输入算术表达式:2*(3+4) 234+* 请输入算术表达式:1+2*(6-4) 1264-*+ 请输入算术表达式:1+2*(5-4)+6-7 1254-*+6+7- 请输入算术表达式:(1+2)*3-4*(6-5) 12+3*465-*-
喝水不忘挖井人,参考资料如下:
1.Java数据结构与算法(第二版) [美]Robert Lafore著
2.栈的应用--中序表达式转后序表达式 https://www.cnblogs.com/bgmind/p/3989808.html
--END--2019年9月2日12点20分
[Java]将算术表达式(中序表达式Infix)转成后续表达式Postfix的更多相关文章
- 二叉树 Java 实现 前序遍历 中序遍历 后序遍历 层级遍历 获取叶节点 宽度 ,高度,队列实现二叉树遍历 求二叉树的最大距离
数据结构中一直对二叉树不是很了解,今天趁着这个时间整理一下 许多实际问题抽象出来的数据结构往往是二叉树的形式,即使是一般的树也能简单地转换为二叉树,而且二叉树的存储结构及其算法都较为简单,因此二叉树显 ...
- PAT-1099(Build A Binary Search Tree)Java实现+二叉排序树的中序遍历和层次遍历
Build A Binary Search Tree PAT-1099 本题有意思的一个点就是:题目已经给出了一颗排序二叉树的结构,需要根据这个结构和中序遍历序列重构一棵二叉排序树. 解法:可以根据中 ...
- PAT-1086(Tree Traversals Again)Java语言实现+根据中序和前序遍历构建树并且给出后序遍历序列
Tree Traversals Again Tree Traversals Again 这里的第一个tip就是注意到非递归中序遍历的过程中,进栈的顺序恰好是前序遍历的顺序,而出栈的顺序恰好是中序遍历的 ...
- C语言实现链式二叉树静态创建,(先序遍历),(中序遍历),(后续遍历)
#include <stdio.h>#include <stdlib.h> struct BTNode{ char data ; struct BTNode * pLchild ...
- IDEA问题java: -source 1.6 中不支持diamond、 lambda 表达式
文章目录 一.问题:连片的java: -source 1.6 中不支持 diamond 运算符.lambda 表达式 二.解决方法: 1.在微信群里问大佬,大佬在玩游戏,回复的比较慢 2.自己查Goo ...
- [Java]算术表达式组建二叉树,再由二叉树得到算式的后序和中序表达式
Entry类: package com.hy; import java.io.BufferedReader; import java.io.IOException; import java.io.In ...
- [Java]算术表达式求值之三(中序表达式转二叉树方案 支持小数)
Entry类 这个类对表达式的合法性进行了粗筛: package com.hy; import java.io.BufferedReader; import java.io.IOException; ...
- [Java]算术表达式求值之二(中序表达式转后序表达式方案,支持小数)
Inlet类,入口类,这个类的主要用途是验证用户输入的算术表达式: package com.hy; import java.io.BufferedReader; import java.io.IOEx ...
- [Java]算术表达式求值之一(中序表达式转后序表达式方案)
第二版请见:https://www.cnblogs.com/xiandedanteng/p/11451359.html 入口类,这个类的主要用途是粗筛用户输入的算术表达式: package com.h ...
随机推荐
- CSS-百分百布局
1.照片随着大小变化: 这里面重点就是每个包裹盒子是25%,图片是100%显示: <div class="box2"> <p> //这里都是4个: < ...
- 独热编码 pandas get_dummies
映射技巧 将'income_raw'编码成数字值 income_mapping = {'<=50K': 0,'>50K': 1} income = income_raw.map(incom ...
- docker 网络 实现
最近在学习docker网络相关的知识,关于网络这块儿记下来,以便review dokcer安装完成之后默认提供三种网络 bridge host none docker默认使用bridge brid ...
- Java的clone方法
现在有User类:(Getter和Setter省略) public class User implements Cloneable { private String name; private int ...
- mui在tab选项卡中echarts图表不能动态随页面变化大小 只能固定大小
在mui tab选项卡中一直都不能让echarts动态变化大小 只能固定大小来展示图表,网上说的window.onresize = mycharts.resize;方法根本就没有效果,后面在https ...
- 18、nginx优化
一.性能优化概述 基询imm能优化,那么在性能优化这一章,我们将分为如下几个方面做介绍 1.首先我们需要了解性能优化要考虑哪些方面. 2.然后我们需要了解性能优化必须要用到的压力测试工具ab. 3.最 ...
- VMWare中CentOS7 设置固定IP且能够访问外网
最近搭建kubernetes集群环境时遇到一个问题,CentOS7在重启后IP发生变化导致集群中etcd服务无法启动后集群环境变得不可用,针对这种情况,必须要对CentOS7设置固定IP且可以访问外网 ...
- PAT Basic 1009 说反话 (20 分)
给定一句英语,要求你编写程序,将句中所有单词的顺序颠倒输出. 输入格式: 测试输入包含一个测试用例,在一行内给出总长度不超过 80 的字符串.字符串由若干单词和若干空格组成,其中单词是由英文字母(大小 ...
- HTML5 App的代码注入攻击
原文链接 摘要 基于HTML5的手机app(译者注:以下简称HTML5 app)越来越流行了, 在大多数情况下它比native应用更容易适配不同的移动操作系统.它开发起来很方便,可以使用标准的web技 ...
- 11jsp
1.JSP 1. 指令 作用:用于配置JSP页面,导入资源文件 格式: <%@ 指令名称 属性名1=属性值1 属性名2=属性值2 ... %> 分类: ...