[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 ...
随机推荐
- javaScript基本使用api
基本方法 isArray() 判断数组 isArray() 方法用于判断是否是数组(有兼容性) 语法:Array.isArray(arr) 返回值:是数组,返回true.不是数组,返回false. i ...
- N1试卷常考词汇总结
免れる まぬがれる 免去,幸免 軽率 けいそつ 轻率,草率 捩れる ねじれる 拧劲儿,扭歪,弯曲 裂ける さける 裂开,破裂 避ける さける 躲避,避开 つまむ 挟,捏,掐 追及 ついきゅう 追上.追 ...
- linux下mysql忘记密码解决方案
一.写随笔的原因:之前自己服务器上的mysql很久不用了,忘记了密码,所以写一下解决方案,以供以后参考 二.具体的内容: 1. 检查mysql服务是否启动,如果启动,关闭mysql服务 运行命令:ps ...
- shell 脚本中的入参获取与判断
1.获取shell脚本的入参个数: $# 2.获取shell脚本的第n个入参的字符个数/字符串长度(注意这里的n需要替换为具体的数字,如果这个数字超过实际的入参个数,结果为0): ${#n}
- 常用数据存储格式之json
常用数据存储格式介绍 JSON: JavaScript Object Notation(JavaScript 对象表示法) JSON 是存储和交换文本信息的语法.类似 XML. JSON 比 XML ...
- 三天读完调整自己每天的精力——读书笔记(Unfinished)
近段时间精力低下,读了一本Jim Loehr的The Power full engagement 精力管理的书,我们有时候往往不是时间规划不够,而是没有规划好自己的精力. 橙色字体是自己对于这本书的现 ...
- qt打印输出到控制台
创建工程的时候是QT Console Application 1.项目->run->Run in terminal 2.pro文件中添加 CONFIG +=console thread ...
- nmap脚本(nse)使用总结
nmap脚本主要分为以下几类,在扫描时可根据需要设置--script=类别这种方式进行比较笼统的扫描: auth: 负责处理鉴权证书(绕开鉴权)的脚本 broadcast: 在局域网内探查更多服务 ...
- 【The 13th Chinese Northeast Collegiate Programming Contest H 题】
题目大意:NOIP2018d1t1 支持 M 次区间查询答案和区间修改操作. 题解: 首先考虑不带区间修改的情况.从左到右进行考虑,发现对于第 i 个数来说,对答案的贡献仅仅取决于第 i-1 个数的大 ...
- 同一域名对应多个IP时,PHP获取远程网页内容的函数
同一域名对应多个IP时,PHP获取远程网页内容的函数 [文章作者:张宴 本文版本:v1.0 最后修改:2008.12.15 转载请注明原文链接:http://blog.zyan.cc/post/389 ...