数据结构Java实现06----中缀表达式转换为后缀表达式

2023-11-14

本文转载至:http://www.cnblogs.com/smyhvae/p/4790373.html

本文主要内容:

  • 表达式的三种形式
  • 中缀表达式与后缀表达式转换算法

一、表达式的三种形式:

  • 中缀表达式:运算符放在两个运算对象中间,如:(2+1)*3。我们从小做数学题时,一直使用的就是中缀表达式。
  • 后缀表达式:不包含括号,运算符放在两个运算对象的后面,所有的计算按运算符出现的顺序,严格从左向右进行(不再考虑运算符的优先规则),如:2 1 + 3 *。又比如3+(6-4/2)*5=23的后缀表达式为:3642/-5*+# (#符号为结束符)
  • 前缀表达式:同后缀表达式一样,不包含括号,运算符放在两个运算对象的前面,如:* + 2 1 3 。前缀表达式和后缀表达式其实是差不多的,只不过符号位置不同而已,前缀表达式不是很常见。

 

二、中缀表达式转换为后缀表达式:(思路)

1、将中缀表达式转换为后缀表达式:(步骤,有点难理解)

(1)当读到数字直接送至输出队列中;

(2)当读到运算符t时:

  a.将栈中所有优先级高于或等于t的运算符弹出,送到输出队列中;

    注:这句话不好理解,可以说成这样,从栈顶开始,依次弹出比当前处理的运算符优先级高的运算符,直到一个比它优先级低的或者遇到了一个左括号就停止

  b.t进栈;

(3)读到左括号时总是将它压入栈中;

(4)读到右括号时,将靠近栈顶的第一个左括号上面的运算符全部依次弹出,送至输出队列后,再丢弃左括号;

(5)中缀表达式全部读完后,若栈中仍有运算符,将其送到输出队列中。

 

举例:

124b3dd7-f3b3-4110-904c-8a2b1d85dccd

上图中,左侧的那一列为输出序列,右侧的那一列为栈。

2、运用后缀表达式进行计算:

  (1)建立一个栈S;

  (2)从左到右读后缀表达式,读到数字就将它转换为数值压入栈S中,读到运算符则从栈中依次弹出两个数分别到Y和X,然后以“X 运算符 Y”的形式计算机出结果,再压加栈S中;

  (3)如果后缀表达式未读完,就重复上面过程,最后输出栈顶的数值则为结束。

举例:

3+(2-5)*6/3=-3 ,其后缀表达式为:325-6*3/+。其运算结果如下:

45270e43-7c61-4ac2-af8f-efb437e8d742

三、代码实现:将中缀表达式转换为后缀表达式

  • JDK  Stack类使用
  • 使用泛型

代码实现:

(1)StringToArithmetic.java:(中缀表达式转化为后缀表达式的工具类

  1 /**
  2  * Created by smyhvae on 2015/9/7.
  3  * 工具类:
  4  * 1、中缀表达式转化为后缀表达式
  5  * 2、给出一个算术表达式(中缀表达式),直接得到计算结果
  6  */
  7 
  8 import java.util.Stack;
  9 import java.util.regex.Pattern;
 10 
 11 public class StringToArithmetic {
 12 
 13     private StringToArithmetic() {
 14     }
 15 
 16     //方法:给出一个算术表达式(中缀表达式),得到计算结果。 例如 (5+8+10)*1,返回23
 17     public static double stringToArithmetic(String string) {
 18         return suffixToArithmetic(infixToSuffix(string));
 19     }
 20 
 21     /**
 22      * 中缀表达式转后缀表达式 只处理了+,-,*,/和括号,没有处理负号及其它运算符,也没对前缀表达式验证。
 23      * 如要处理负号,可对表达式进行预转义处理,当下面条件成立时,将负号换成单目运算符"!" infix.charAt[i]=='-'&&(
 24      * i==0||infix.charAt[i-1]=='(')
 25      * 3*6/4+3
 26      * 3+6-4           3 6 + 4 -
 27      * 3+(6-4/2)*5    3 6 4 2 / - 5 * +
 28      */
 29     //方法:中缀表达式转成后缀表达式
 30     public static String infixToSuffix(String infix) {
 31         Stack<Character> stack = new Stack<Character>();
 32         String suffix = "";
 33         int length = infix.length();
 34         for (int i = 0; i < length; i++) {
 35             Character temp;
 36             char c = infix.charAt(i);
 37             switch (c) {
 38                 // 忽略空格
 39                 case ' ':
 40                     break;
 41                 // 碰到'(',push到栈
 42                 case '(':
 43                     stack.push(c);
 44                     break;
 45                 // 碰到'+''-',将栈中所有运算符弹出,送到输出队列中
 46                 case '+':
 47                 case '-':
 48                     while (stack.size() != 0) {
 49                         temp = stack.pop();
 50                         if (temp == '(') {
 51                             stack.push('(');
 52                             break;
 53                         }
 54                         suffix += " " + temp;
 55                     }
 56                     stack.push(c);
 57                     suffix += " ";
 58                     break;
 59                 // 碰到'*''/',将栈中所有乘除运算符弹出,送到输出队列中
 60                 case '*':
 61                 case '/':
 62                     while (stack.size() != 0) {
 63                         temp = stack.pop();
 64                         if (temp == '(' || temp == '+' || temp == '-') {
 65                             stack.push(temp);
 66                             break;
 67                         } else {
 68                             suffix += " " + temp;
 69                         }
 70                     }
 71                     stack.push(c);
 72                     suffix += " ";
 73                     break;
 74                 // 碰到右括号,将靠近栈顶的第一个左括号上面的运算符全部依次弹出,送至输出队列后,再丢弃左括号
 75                 case ')':
 76                     while (stack.size() != 0) {
 77                         temp = stack.pop();
 78                         if (temp == '(')
 79                             break;
 80                         else
 81                             suffix += " " + temp;
 82                     }
 83                     // suffix += " ";
 84                     break;
 85                 //如果是数字,直接送至输出序列
 86                 default:
 87                     suffix += c;
 88             }
 89         }
 90 
 91         //如果栈不为空,把剩余的运算符依次弹出,送至输出序列。
 92         while (stack.size() != 0) {
 93             suffix += " " + stack.pop();
 94         }
 95         return suffix;
 96     }
 97 
 98 
 99     /**
100      * postfix
101      *
102      * @return double
103      */
104     //方法:通过后缀表达式求出算术结果
105     public static double suffixToArithmetic(String postfix) {
106 
107         Pattern pattern = Pattern.compile("\\d+||(\\d+\\.\\d+)"); //使用正则表达式 匹配数字
108         String strings[] = postfix.split(" ");  //将字符串转化为字符串数组
109         for (int i = 0; i < strings.length; i++)
110             strings[i].trim();  //去掉字符串首尾的空格
111         Stack<Double> stack = new Stack<Double>();
112 
113         for (int i = 0; i < strings.length; i++) {
114 
115             if (strings[i].equals(""))
116                 continue;
117 
118             //如果是数字,则进栈
119             if ((pattern.matcher(strings[i])).matches()) {
120 
121                 stack.push(Double.parseDouble(strings[i]));
122             } else {
123                 //如果是运算符,弹出运算数,计算结果。
124                 double y = stack.pop();
125                 double x = stack.pop();
126                 stack.push(caculate(x, y, strings[i])); //将运算结果重新压入栈。
127             }
128         }
129         return stack.pop(); //弹出栈顶元素就是运算最终结果。
130 
131     }
132 
133     private static double caculate(double x, double y, String simble) {
134         if (simble.trim().equals("+"))
135             return x + y;
136         if (simble.trim().equals("-"))
137             return x - y;
138         if (simble.trim().equals("*"))
139             return x * y;
140         if (simble.trim().equals("/"))
141             return x / y;
142         return 0;
143     }
144 }

(2)Test.java:(测试类)

 1 public class Test {
 2     public static void main(String[] args) {
 3 
 4         String str = "3+(2-5)*6/3";  //其后缀表达式为325-6*3/+
 5 
 6         //调用方法:中缀表达式转成后缀表达式
 7         System.out.println(StringToArithmetic.infixToSuffix(str));
 8 
 9         //调用方法:给出一个算术表达式(中缀表达式),得到计算结果
10         System.out.println(StringToArithmetic.stringToArithmetic(str));
11 
12     }
13 
14 }

上方代码中,第07行是根据中缀表达式算出后缀表达式。

第10行:是给出一个中缀表达式,直接的到计算结果,其实它的步骤是:先根据中缀表达式得到后缀表达式,然后根据后缀表达式去计算结果

运行效果:

68bb3685-b736-4d3b-95ad-6a6981b80071


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

数据结构Java实现06----中缀表达式转换为后缀表达式 的相关文章

  • 微信小程序animation

    wxml
  • LINUX 查询已安装的软件信息

    问题 1 列出当前主机已安装的所有RPM软件 2 查看firefox软件包的安装清单 3 查询ifconfig命令程序是安装哪个软件包后产生的 4 查看firefox软件包的用途 方案 查询所有已安装的rpm包 可以利用命令rpm qa 查
  • CentOS 修改IP地址, DNS, 网关

    一 CentOS 修改IP地址 修改对应网卡的IP地址的配置文件 vi etc sysconfig network scripts ifcfg eth0 修改以下内容 DEVICE eth0 描述网卡对应的设备别名 例如ifcfg eth0
  • 【满分】【华为OD机试真题2023 JAVA&JS】整理扑克牌

    华为OD机试真题 2023年度机试题库全覆盖 刷题指南点这里 整理扑克牌 知识点贪心排序 时间限制 1s 空间限制 256MB 限定语言 不限 题目描述 给定一组数字 表示扑克牌的牌面数字 忽略扑克牌的花色 请按如下规则对这一组扑克牌进行整
  • 【Linux】远程连接服务

    1 什么是远程连接服务器 远程连接服务器通过文字或图形接口方式来远程登录系统 让你在远程终端前登录linux主机以取得可操作主机接口 shell 而 登录后的操作感觉就像是坐在系统前面一样 2 远程连接服务器的功能 分享主机的运算能力 服务
  • 服务器传感器不显示,服务器传感器不显示

    服务器传感器不显示 内容精选 换一换 不建议将挂载至Linux系统云服务器的云硬盘卸载后 重新挂载至Windows系统云服务器 也不建议将Windows系统云服务器上的云硬盘重新挂载至Linux系统云服务器 在这种情况下 由于文件系统不一致

随机推荐

  • C++ Primer阅读笔记--函数重载和内联函数

    1 函数重载 main 函数不能重载 重载函数在形参数量或形参类型上有所不同 不允许两个函数除了返回类型外其他所有的要素都相同 即函数重载不允许只有返回类型不同 如果形参是某种类型的指针或引用 则通过区分其指向的是常量对象还是非常量对象可以
  • php 日期1900年开始,php日期操作函数

    header content type text html charset utf 8 总结php操作时间的函数 1 cal days in month calendar month year 函数针对指定的年份和日历 返回一个月中的天数
  • Https如何保证了数据的安全?

    Https与Http在数据传输过程的差别 Https与Http都是OSI模型中传输层协议 而唯一不同的就是Https中在Http的应用层和TCP IP增加了一个SSL TLS层 其实也是属于应用层 主要用来对数据进行加解密 保证数据的传输的
  • 服务器系统环境初始化,Centos7系统

    服务器初始化环境 更新yum源 并添加必要系统工具 修改时区 设置系统时间 ntpdate时间同步服务 修改字符集zh CN UTF 8 关闭selinux 内核优化sysctl conf 调整文件描述符ulimit 即单个进程的最大文件打
  • 模拟电路设计的九个级别,你是模电几段?

    众 生 所 搬 周 硬 知 套 模拟电路设计的九个级别 类似下围棋的段位 快来看看自己处于什么水平 感觉九段已经是世外高人了 一段 你刚开始进入这行 对PMOS NMOS BJT什么的只不过有个大概的了解 各种器件的特性你也不太清楚 具体设
  • VSCode——修改VSCode背景图片

    1 以管理员身份运行VS Code 安装background插件 2 打开设置 在搜索框中输入background 选择扩展中的plugin background 选择在setting json中编辑 3 在用户设置中输入以下代码 修改完后
  • [QT入门篇]信号槽机制

    一 信号与槽的引入 信号与槽 Signal Slot 是 Qt 编程的基础 信号槽 实际是观察者模式 发布 订阅模式 当某个事件发生之后 比如 按钮检测到自己被点击了一下 它就会发出一个信号 signal 这种发出是没有目的的 类似广播 如
  • 【NLP】第 1 章 :机器阅读理解简介

    大家好 我是Sonhhxg 柒 希望你看完之后 能对你有所帮助 不足请指正 共同学习交流 个人主页 Sonhhxg 柒的博客 CSDN博客 欢迎各位 点赞 收藏 留言 系列专栏 机器学习 ML 自然语言处理 NLP 深度学习 DL fore
  • Python可视化-气泡图

    气泡图类似散点图 也是表示XY轴坐标之间的变化关系 也可以像彩色散点图给点上色 区别在于可以通过图中散点的大小来直观感受其所表示的数值大小 一 数据文件准备 1 PeopleNumber csv city people price NJ 8
  • Android VNDK的作用

    本文目的是让你理解VNDK是什么作用 暂不做细节讲解 在Android 8 0及更高版本中 引入了很多技术都是为了将system和vendor分离 这样设备厂商和芯片供应商只需关心vendor实现 那么vendor实现时要加载framewo
  • 【总结】前端常用编码写法合集

    一 css样式 1 文字多行溢出 单行溢出 overflow hidden white space nowrap text overflow ellipsis 多行溢出 display webkit box webkit box orien
  • Vue教程(一):Vue核心

    Vue教程 一 Vue核心 1 1 Vue简介 1 1 1 Vue是什么 一套用于构建用户界面的渐进式JS框架 1 1 2 谁开发的 尤雨溪 2015 10 27 正式发布 Vue1 0 0 Evangelion 新世纪福音战士 2016
  • C语言 结构体初阶

    头文件 define CRT SECURE NO WARNINGS 1 include
  • 毕设系列三之利用tensorflow做深度学习情感分析

    利用tensorflow做深度学习情感分析 深度学习作为一项学习数据的多层特征或表征的强大机器学习技术 此项目中 将使用tensorflow深度学习平台 通过相关模型的构建 以及数据的处理 完成微博评论情感分析 已到达类似百度AI情感分析功
  • 多态(polymorphic)

    目录 1 多态的基本介绍 2 多态实现条件 3 重写 重写的介绍 重写和重载的区别 动 静态绑定机制 5 向上转型和向下转型 向上转型 向上转型的特点 总结 向下转型 多态的优缺点 多态是Java三大基本特征中最抽象也是最重要的特征 多态是
  • Html获取Url参数 解决中文乱码

    Html 获取 Url 参数 解决中文乱码 方法一 分割为数组 function getQueryVariable name var query window location search substring 1 var vars que
  • hibernate 反向生成数据库表

    hibernate 配置属性中 hibernate hbm2ddl auto可以帮助你实现正向工程 即由 java 代码生成数据库脚本 进而生成具体的表结构 在hibernate cfg xml中 java 代码 html view pla
  • idea

    1 本人最近刚开始切换到 Intellij idea 发现一个问题 maven工程项目老是有红色下划线提示错误 Cannot Resolve Symbol 但是这些依赖都已经通过pom引进了 idea的Library中也能看到 试一下Fil
  • mysql 建表语句 及完整案例

    1 最简单的 表名为name info 只包含id列和name列 执行sql语句 CREATE TABLE name info id int not null name char 12 2 将id列设置为主键 执行sql语句 CREATE
  • 数据结构Java实现06----中缀表达式转换为后缀表达式

    本文转载至 http www cnblogs com smyhvae p 4790373 html 本文主要内容 表达式的三种形式 中缀表达式与后缀表达式转换算法 一 表达式的三种形式 中缀表达式 运算符放在两个运算对象中间 如 2 1 3