栈的应用之中缀表达式转后缀
来源:互联网 发布:蚌埠学院网络 编辑:程序博客网 时间:2024/05/17 13:39
前言
栈的一个广泛应用就是讲中缀表达式转换为后缀表达式。所谓中缀表达式就是我们从小到大所接触的:10+3-6/2+4*5 之类的算数表达式。而后缀表达式又称为逆波兰表达式,
它是由波兰逻辑学家J.Lukasiewicz于1929年提出的。
为什么需要后缀表达式
对于计算机而言,后缀表达式非常方便进行运算。举例来说,对于 "3,5,+," 这样的后缀表达式,其算法如下:
从左至右读取每个字符,若是数字,则入栈;若是操作符,则作用于栈中所弹出的两个数字。
转换算法
那么如何将中缀表达式转换为后缀呢?最简单的步骤如下:
1.按照优先级将整个表达式从里到外加满括号
2.将操作符移动到距离被操作数最近的括号外
3.去掉所有括号后的结果即为后缀表达式。
按照上面的步骤,我们对 10+3-6/2+4*5 进行转换:
第一步:加括号
(((10+3)-(6/2))+(4*5))
第二步:移动操作符
第三步:去掉括号
10 3 + 6 2 /- 4 5 * +
对于人类而言,这是最简单的一种办法了。但是本文的目的是描述中缀转换后缀的程序算法。
算法如下:
初始化一个空栈来保存操作符
循环中缀表达式中每一个字符:
1.当读到操作数时,立即把它放到输出中。操作符不立即输出,而是放进栈中。
2.当遇到左括号时,也将其放到栈中。
3.如果见到一个右括号,那么我们将栈元素弹出,将弹出的符合写出直到我们遇见一个(对应的)左括号,但是
这个左括号,只弹出,不输出。
4.如果我们见到任何其他的符号(“+”,“-”,“*”,“/”,"("),则循环弹出栈顶元素到输出,
直到遇见优先级更低的元素为止(也就是说:如果栈顶符号的优先级大于等于当前符号的优先级,则从栈中弹出元素到输出。)。
有一个例外:除非是在处理一个“)”的时候,否则我们绝不从栈中移走“(”。对于这种操作,“+”的优先级最低,而“(”的优先级
最高。当从栈中弹出元素的工作完成后,我们再将操作符入栈。
5.最后,如果我们读到输入的末尾,我们将栈元素弹出,直到栈变为空栈,将弹出的元素写到输出。
完整的代码如下:
package com.lemon.stack;import java.util.ArrayList;import java.util.List;import java.util.Stack;import java.util.StringTokenizer;import java.util.regex.Pattern;public class PostfixConverter {public static void main(String[] args) {//String infixExpression="10+3-6/2+4*5";String infixExpression="(((10+3)-(6/2))+(4*5))";buildPostfixExpression(infixExpression);}public static List<String> buildPostfixExpression(String infixExpression){List<String> result=new ArrayList<String>();Stack<String> operatorStack=new Stack<String>();StringTokenizer strTokenizer = new StringTokenizer(infixExpression, "+-*/()", true);String currentEle;while (strTokenizer.hasMoreTokens()) { currentEle = strTokenizer.nextToken().trim();if(currentEle!=null && !currentEle.equals("")){if(isDigital(currentEle)){result.add(currentEle);}else if(currentEle.equals("(")){operatorStack.push(currentEle);}else if(currentEle.equals(")")){while(!operatorStack.isEmpty() && !operatorStack.peek().equals("(")){result.add(operatorStack.pop());}operatorStack.pop();}else if(currentEle.equals("+")||currentEle.equals("-")||currentEle.equals("*")||currentEle.equals("/")||currentEle.equals("(")||currentEle.equals(")")){while(!operatorStack.isEmpty() &&(!currentEle.equals(")") && !operatorStack.peek().equals("("))&&getPriority(operatorStack.peek())>=getPriority(currentEle)){result.add(operatorStack.pop());}operatorStack.push(currentEle);}}}while(!operatorStack.isEmpty()){result.add(operatorStack.pop());}System.out.println(result.toString());return result;}public static int getPriority(String operator){if(operator.equals("+")||operator.equals("-")){return 1;}else if(operator.equals("*")||operator.equals("/")){return 2;}else if(operator.equals("(")){return 3;}return 0;}/** * 判断字符串是否是数字类型 * @param str * @return true:数字;false:非数字 */ public static boolean isDigital(String str) { String numRegex = "^\\d+(\\.\\d+)?$"; return Pattern.matches(numRegex, str); } }
- 栈的应用实践之中缀表达式转后缀表达式
- 栈的应用之中缀表达式转后缀表达式
- 栈的重要应用之中缀转后缀表达式算法
- 栈的应用之中缀表达式转后缀
- 栈的应用之中缀表达式转换为后缀表达式
- 中缀表达式转后缀表达式求值(栈的应用)
- 栈的应用-中缀表达式转后缀表达式(C版)
- 栈的应用 - 中缀表达式转后缀表达式
- 栈的应用案例2:中缀表达式转后缀表达式
- 栈的应用---(中缀表达式 转 后缀表达式)
- 《数据结构实战》中缀表达式转后缀表达式----栈的应用
- 栈应用之中缀转后缀表达式(C语言版)
- 栈的应用——中缀表达式转后缀表达式,后缀表达式的求值,中缀表达式求值
- 栈的应用—中缀转后缀求表达式值
- 栈的应用--表达式计算&中缀转后缀
- 栈应用(中缀表达式转后缀表达式并计算后缀表达式的值)
- python数据结构与算法 10 栈的应用之中缀转后缀表达式算法的实现
- 栈的应用--算术表达式的求值(中缀转后缀然后计算后缀表达式的值)
- 面试之路(26)-面试相关的位运算总结
- 获取用户原始IP地址
- 经典 Spring 面试题和答案
- 深入理解Java的接口和抽象类
- easyui-DataGrid基本用法
- 栈的应用之中缀表达式转后缀
- Python3使用requests模块显示下载进度
- C++中的随机数函数
- KMP模板(2203)
- LM8 + 放大电路
- The currently displayed page contains invalid values
- Html5 手机网页中,长按会触发系统事件,请问怎么取消这些事件?
- View位置参数
- reactNative白屏优化