如何生成后缀表达式

  如果计算一个表达式,比如 4+5+6*2,随着计算器的不同,简单的四功能计算器是30,许多科学计算器知道乘法的优先级高于加法,所以科学答案是21。典型计算顺序可以是计算4+5,存为临时变量a,再计算6*2,存为b,最后计算a+b可得出最后结果。这种操作顺序如下:45+62*+

  这种记法就是后缀表达式,其求值的过程就是上面描述的整个过程。那如何生成后缀表达式呢,也就是从中缀表达式转换为后缀表达式,可以借助于栈来实现,整个步骤如下:

  1. 依次读取输入的表达式,如果是操作数,则把它放入到输出中。
  2. 如果是操作符,栈为空的话直接将该操作符入栈;如果栈非空,则比较栈顶操作符和该操作符优先级,如果栈顶操作符优先级小于该操作符,则该操作符入栈;否则弹出栈顶操作符并将其放入到输出中,直到栈为空或者发现优先级更低的操作符为止。
  3. 如果是括号,比如'('和')',则特殊处理。如果是'('的话,直接入栈;如果是')',那么就将栈顶操作符弹出写入到输出中,直到遇到一个对应的'(',但是这个'('只弹出不写入到输出中。注意:"("可以理解为优先级最高。
  4. 当表达式读取完毕后,如果栈中还有操作符,则依次弹出操作符并写入到输出中。

 

比如(1+2)*(3+2)-4/2表达式,其后缀表达式和计算结果为:

Java示例代码如下:

import java.util.ArrayList;
import java.util.List;
import java.util.Stack;/*** MyComputer*/
public class MyComputer {public static int computer(String input) {List<String> cutList = cutInput(input);List<String> afterList = getAfterList(cutList);return getResultFromAfterList(afterList);}/*** 根据后缀表达式计算结果*/private static int getResultFromAfterList(List<String> afterList) {Stack<Integer> stack = new Stack<>();for (String ele : afterList) {if (isFlag(ele.charAt(0))) {int b = stack.pop();int a = stack.pop();stack.push(cal(a, b, ele.charAt(0)));} else {stack.push(Integer.valueOf(ele));}}if (stack.size() != 1) {throw new StackOverflowError();}return stack.pop();}/*** 获取两个数的计算结果*/private static int cal(int a, int b, char flag) {int result = 0;switch (flag) {case '+': {result = a + b;break;}case '-': {result = a - b;break;}case '*': {result = a * b;break;}case '/': {result = a / b;break;}default: {break;}}return result;}/*** 生成后缀表达式*/private static List<String> getAfterList(List<String> cutList) {List<String> output = new ArrayList<>();Stack<Character> stack = new Stack<>();for (String ele : cutList) {char flag = ele.charAt(0);if (isFlag(ele.charAt(0)) || (flag == '(') || (flag == ')')) {// 计算符入栈if (stack.isEmpty()) {stack.push(flag);} else {// 如果待入栈计算符大于栈顶计算符,则直接入栈;否则出栈直到栈为空或者待入栈计算符小于栈顶计算符if (flag == '(') {stack.push(flag);} else if (flag == ')') {while (stack.peek() != '(') {output.add(String.valueOf(stack.pop()));}stack.pop();}else if (isFlagSmaller(stack.peek(), flag)) {stack.push(flag);} else if (stack.peek() == '(') {stack.push(flag);} else{do {if (stack.peek() == '(') {break;}output.add(String.valueOf(stack.pop()));} while (!stack.isEmpty() && !isFlagSmaller(stack.peek(), flag));stack.push(flag);}}} else {// 数字直接添加到输出中
                output.add(ele);}}while (!stack.isEmpty()) {if ((stack.peek() != '(') || (stack.peek() != ')')) {output.add(String.valueOf(stack.pop()));}}return output;}/*** 将字符串以操作符为分隔符切片*/private static List<String> cutInput(String input) {List<String> cutList = new ArrayList<>();boolean running = true;while ((input.length() > 0) && running) {char c = input.charAt(0);if (isFlag(c) || (c == '(') || (c == ')')) {cutList.add(String.valueOf(c));input = input.substring(1);} else {for (int i = 0; i < input.length(); i++) {char tmpC = input.charAt(i);if (isFlag(tmpC) || (tmpC == '(') || (tmpC == ')')) {cutList.add(input.substring(0, i));cutList.add(String.valueOf(tmpC));input = input.substring(i + 1);break;}if (i == input.length() - 1) {cutList.add(input);running = false;}}}}return cutList;}/*** 判断一个字符是否是操作符*/private static boolean isFlag(char c) {return (c == '+' || c == '-' || c == '*' || c == '/');}/*** 第一个操作符优先级是否小于第二个*/private static boolean isFlagSmaller(char a, char b) {boolean flag = true;switch (a) {case '+':case '-': {if ((b == '+') || (b == '-')) {flag = false;}break;}case '*':case '/': {flag = false;}case '(': {flag = false;}default: {break;}}return flag;}
}

 

后缀表达式和表达式树

  表达式树是由后缀表达式构造而来的,那么如何构造呢,也是借助于栈来实现。上述代码已经实现了从中缀表达式转换为为后缀表达式,整个步骤大致如下:

  1. 依次遍历后缀表达式,如果是如果是操作数,则以其为数据创建一个单节点书,然后将该树入栈。
  2. 如果是操作符,则从栈中弹出2棵树T1和T2(T1先弹出)并形成一个新的书,该树的根就是该操作符,左右孩子分别是T2和T1,然后将这棵新树入栈。
  3. 最后栈中会剩下一棵树,则这棵树就是表达式树。具体代码可以参考表达式树。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/259621.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【原生JS插件】LoadingBar页面顶部加载进度条

先展示一下已经实现的效果&#xff1a; 预览地址&#xff1a;http://dtdxrk.github.io/js-plug/LoadingBar/index.html 看到手机上的浏览器内置了页面的加载进度条&#xff0c;想用在pc上。 网上搜了一下&#xff0c;看到几种页面loading的方法&#xff1a; 1.在body头部加入lo…

qtp启动java程序_转: QTP六脉神剑之调用Java程序

查看( 1147 ) /评论( 21 )六脉神剑之调用程序0Xp1zLN_0版权声明&#xff1a;原创作品&#xff0c;转载请以链接方式注明出自http://www.51testing.com/?35&#xff0c;否则将追究法律责任。51Testing软件测试网y|X,taS51Testing软件测试网b;|w6I"g6oK本文出自songfun的51…

Linq 数据库操作(增删改查)

Linq数据库增删改查 Linq是一种查询语言&#xff0c;集成包含在formwork中&#xff0c;包含在C#语言中&#xff0c;它的作用是降低查询的门槛&#xff0c;提高开发效率&#xff0c;是我们必须掌握的技术之一&#xff0c;下面是我自己对linq数据库操作的方法&#xff0c;与大家…

第八章 Python 对象和类

一、什么是对象 在 Pyth 中&#xff0c;对象就是经过实例化的&#xff0c;具体可以操作的一组代码的组合&#xff1b; 对象一般包含数据&#xff08;变量&#xff0c;更习惯称之为属性 attribute&#xff09;&#xff0c;也包含代码&#xff08;函数&#xff0c;也称之为方法&a…

JS同名方法,

JS同名方法只会调用最后一个方法。 JS中同时绑定多个事件&#xff0c;先绑定的先调用。后绑定的后调用。转载于:https://www.cnblogs.com/daishuguang/p/4169718.html

Spring WebSocket初探2 (Spring WebSocket入门教程)

2019独角兽企业重金招聘Python工程师标准>>> WebSocket前端准备 SockJS&#xff1a; SockJS 是一个浏览器上运行的 JavaScript 库&#xff0c;如果浏览器不支持 WebSocket&#xff0c;该库可以模拟对 WebSocket 的支持&#xff0c;实现浏览器和 Web 服务器之间低延迟…

软件测试相关概念与分类

这是我看了有关软件测试的书的一些归纳与总结。 软件测试的核心是发现软件中的缺陷。测试是对软件质量的度量。 一、缺陷 缺陷&#xff0c;目前没有标准定义 。与缺陷相关的一组定义就有&#xff1a;软件错误、软件缺陷、软件故障、软件失效。 软件错误&#xff1a;在软件生存周…

excel SUBTOTAL函数使用详解

转自&#xff1a;http://www.kuqin.com/shuoit/20110524/91710.html 今天用Excel在进行业务统计时&#xff0c;遇到一个小问题&#xff0c;Google了一下&#xff0c;又学了一招。 一般人都会使用“自动筛选”功能&#xff0c;筛选完成后&#xff0c;会在表格左下角的状态栏中提…

java九宫格问题课程设计_课程设计九宫格数独.doc

课程设计九宫格数独中南民族大学管理学院学生课程设计报告课题名称&#xff1a; java课程设计选题名称&#xff1a; 九宫格数独年 级&#xff1a; 2009专 业&#xff1a; 信息管理与信息系统学 号&#xff1a;姓 名&#xff1a;指导教师&#xff1a;完成地点&#xff1a; 管理学…

Scrapy使用问题整理(转载)

转载自&#xff1a;http://blog.csdn.net/heu07111121/article/details/50832999最近尝试使用Scrapy进行数据抓取&#xff0c;并尝试在windows7 64位系统上安装scrapy&#xff0c;下面总结记录遇到两个问题和解决方法&#xff1a;scrapy官网的地址为&#xff1a;http://scrapy.…

英文Ubantu系统安装中文输入法

以前都是安装的中文Ubantu&#xff0c;但是有时候用命令行的时候中文识别不好&#xff0c;会出现错误&#xff0c;所以这次安装了英文版&#xff0c;但是安装后发现输入法不好用&#xff0c;于是就要自己安装输入法。 安装环境为Ubantu13.04 1.卸载Ubantu默认的ibus输入法 sudo…

控制文件初探

1、个数和位置的管理&#xff08;因为控制文件时在参数文件定义的&#xff0c;所以可以直接修改参数文件&#xff09; SPfile修改的步骤&#xff1a;a) 修改SPFILE参数control_filesb) 一致性关闭数据库c) 增加或减少控制文件d) 启动数据库使用SPFILEe) 验证结果 实验&#xff…

String类的使用 Part2

StringBuilder 类的使用 属性&#xff1a; namespace StringBuilderTest {class Program{static void Main(string[] args){StringBuilder s new StringBuilder("hello,world!");Console.WriteLine(s);//Length属性Console.WriteLine("s.Length{0}", s.Le…

JAVA项目怎么不是蓝色_解决IDEA创建maven项目时pom.xml没有变蓝的问题

如下所示&#xff1a;选中pom.xml&#xff0c;右键点击add as maven project&#xff0c;稍等片刻后就可以了补充知识&#xff1a;Idea导入maven项目不自动识别pom.xml*Idea导入maven项目不自动识别pom.xml*当在idea中导入maven项目时&#xff0c;不能自动识别pom文件解决方法&…

C# 6.0:Expression – Bodied Methods

Expression-bodied 方法是C# 6.0 中另一个能简化代码的特性。我们已经对lambda表达式将funciton和delegation关联起来的这种用法很熟悉了。Expression-bodied 将lambda 表达式的这种用法扩展到了方法上。 像下面代码所示&#xff0c;我们有一个GetTime() 方法返回一个格式化的时…

zabbix3.0安装

本次安装准备安装3.0的zabbix(LNMP)第一步 安装zabbix官方的zabbix源&#xff0c;地址如下&#xff1a;http://repo.zabbix.com/zabbix/3.0/rhel/6/x86_64/zabbix-release-3.0-1.el6.noarch.rpm安装zabbix的官方源rpm -ivh zabbix-release-3.0-1.el6.noarch.rpm第二步 使用yu…

android UI自动化测试工具Robotium VS NativeDriver VS Calabash

http://kongqingyun123.blog.163.com/blog/static/6377283520126294029822/ 自从上次对Robotium和nativedriver这两个工具做对比已经过去将近一年的时间了&#xff08;上次内容见http://kongqingyun123.blog.163.com/blog/static/637728352011614111010446/&#xff09;&#x…

POJ 1228 Grandpa's Estate --深入理解凸包

题意&#xff1a; 判断凸包是否稳定。 解法&#xff1a; 稳定凸包每条边上至少有三个点。 这题就在于求凸包的细节了&#xff0c;求凸包有两种算法&#xff1a; 1.基于水平序的Andrew算法 2.基于极角序的Graham算法 两种算法都有一个类似下面的语句&#xff1a; for(int i0;i&…

赵强老师免费公开课第一季:Hadoop的背景起源

标签&#xff1a;免费直播课 Hadoop 大数据 赵强原创作品&#xff0c;允许转载&#xff0c;转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://51edu.blog.51cto.com/8899635/1897555 Hadoop大数据免费公开课招募啦~~~赵强…

.NET Windows服务应用程序

此文旨在记录个人对windows服务的理解以及学习记录&#xff0c;高人可以直接绕行。 1.Windows 服务体系结构 http://technet.microsoft.com/zh-cn/library/aa998749(vexchg.65).aspx Windows 服务&#xff08;也称服务应用程序&#xff09;是无论用户是否登录都运行在 Windows …