如何生成后缀表达式

  如果计算一个表达式,比如 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…

第八章 Python 对象和类

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

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

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

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() 方法返回一个格式化的时…

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 …

bootstrap-代码-内联代码

说明通过 <code> 标签包裹内联样式的代码片段示例<!DOCTYPE html> <html lang"zh-CN"><head><meta charset"utf-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"view…

java类似php魔术方法_PHP与类有关的几个魔术方法

与类有关的其他魔术方法序列化与反序列化技术含义&#xff1a;序列化&#xff1a;就是将一个变量所代表的“内存”数据&#xff0c;转换为“字符串”形式并持久保存在硬盘上的一种做法。反序列化&#xff1a;就是将序列化之后保存在硬盘上的“字符串数据”&#xff0c;恢复为其…

IIS ARR设置HTTP跳转到HTTPS

GUI Version - Select the website you wish to configure- In the “Features View” panel, double click URL Rewrite You will notice there are currently no rules configured for this site. Click “Add Rules…” in the Actions menu to the right of the “Features…

AutoCAD.NET API 最新(2012)教程下载及在线视频教程DevTV

Autodek最近发布了基于最新版的AutoCAD 2012的.net API开发教程。基本内容包括&#xff1a; Overview of .NETPlugin BasicsUser InteractionDatabase fundamentalsDictionariesUser InterfaceEventsInputPoint MonitorJigs现在就可以从AutoCAD开发者中心下载&#xff0c; 看图…

install python_python install on windows 10

图 1官网2、下载安装包&#xff1a;图 2 Downloads – windows图 3选择版本图 4选择离线安装版本图 5保存下载文件—文件名自己可以修改可能有人看到windows 几个版本&#xff0c;对几个版本有迷惑的地方&#xff0c;解释图 6几个版本的差异说明文字解释&#xff1a;An e…

iOS开发常见错误

错误1&#xff1a; 1.1这种错误都是storyboard有问题 解决&#xff1a;当前storyboard的Custom Class是MJViewController&#xff0c;代码中MJViewController继承自UITableViewController。 而storyboard目前提供的是UIViewController&#xff0c;并没有为MJViewController提供…

windows bat 批处理 !vm 合并快播文件

今天简单的写了一个bat批处理文件 用来处理快播的p2p的文件&#xff0c;一般回事这样的目录 你可以下载如下代码 echo off for /r %%a in (.) do (echo %%acd %%acopy /b *.!mv test.rmvb ) pause保存为merge.bat&#xff0c;就可以执行了 代码解释&#xff1a; 扫描该目录下的…

sso接口的调用

之前一直想sso接口已经写好了&#xff0c;登录注册功能是怎么调用的呢&#xff1f;原来在登录注册的jsp页面实现的接口的调用&#xff0c;页面的校验和验证功能在jsp页面即可实现。 注册页面&#xff1a; <% page language"java" contentType"text/html; cha…

[逆向][Writeup]ISG2015 flagfinder - .NET程序逆向

这个题目同样是一道.NET的逆向题&#xff0c;.NET的逆向方法在之前的博文中已经介绍过&#xff0c;这里不做重复的说明。本题的源程序可以在我的github上下载&#xff1a;https://github.com/gsharpsh00ter/reverse 0x01 逆向 flagfinder为.NET编译的PE文件&#xff0c;用dnSpy…

java 编译原理 字符串_Java编译原理(javac)

Java中的编译分为两个部分&#xff1a;源码文件编译成字节码文件(前端编译)字节码文件被虚拟机加载以后编译成机器码(后端编译)对于开发来说接触的一般都是第一个步骤也就是源码编译成字节码文件(class文件)&#xff0c;第二个步骤开发几乎不会接触&#xff0c;因为这是虚拟机在…