[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 ...
随机推荐
- jQuery效果--隐藏和显示
jQuery hide() 和 show() 通过 jQuery,您可以使用 hide() 和 show() 方法来隐藏和显示 HTML 元素: $("#hide").click( ...
- 多线程编程-- part5.1 互斥锁之公平锁-释放锁
释放公平锁 1.unlock() unlock()在ReentrantLock.java中实现的,源码如下: public void unlock() { sync.release(1); } 说明: ...
- busybox介绍
BusyBox 是一个集成了一百多个最常用linux命令和工具的软件.BusyBox 将许多具有共性的小版本的UNIX工具结合到一个单一的可执行文件.这样的集合可以替代大部分常用工具比如的GNU fi ...
- linux yum 安装及卸载
在Centos中yum安装和卸载软件的使用方法安装方法安装一个软件时yum -y install httpd安装多个相类似的软件时yum -y install httpd*安装多个非类似软件时yum ...
- linux进程间的通信方式
linux进程间的通信 进程间的通信就是不同的进程之间传播或交换信息,进程的用户空间是互相独立,进程之间可以利用系统空间交换信息. 管道 允许将一个进程的标准输出和另一个进程的标准输入连接在一起,主要 ...
- sed命令替换文件内容
reference: https://www.cnblogs.com/starof/p/4181985.html 抓取目录名并修改 ls | grep "XXX" > 1.t ...
- 修改Anaconda启动时默认路径
1.找到Anoconda启动快捷方式,入下图: 2.右击点击属性,进入下图: 3.将第三行的 目标(T): ......D:\Anoconda\Scripts\jupyter-notebook-sc ...
- HDU - 6589 Sequence (生成函数+NTT)
题目链接 设序列a的生成函数$\large f(x)=\sum\limits_{i=0}^{n-1}a_ix^i$,则操作1,2,3分别对应将$f(x)$乘上$\Large\frac{1}{1-x}, ...
- MYSQL数据库事务4种隔离级别及7种传播行为
事务的特性: 原子性:事务的不可分割,组成事务的各个逻辑单元不可分割. 一致性:事务执行的前后,数据完整性保持一致. 隔离性:事务执行不应该受到其他事务的干扰. 持久性:事务一旦结束,数据就持久化到数 ...
- Java如何导入一个新的项目
下面将展示如何将一个项目导入eclipse中 1.点击文件-------->从系统中打开项目 2.选择你要导入的项目所在的目录 3.配置环境 单击项目,选择构建路径------>配置构建路 ...