栈的应用之中缀表达式转后缀

前言

栈的一个广泛应用就是讲中缀表达式转换为后缀表达式。所谓中缀表达式就是我们从小到大所接触的: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);
	}
}

时间: 2024-10-02 08:45:47

栈的应用之中缀表达式转后缀的相关文章

栈的应用之中缀表达式转后缀表达式

1,中缀表达式的定义及为什么要将中缀表达式转换为后缀表达式? 中缀表达式(中缀记法) 中缀表达式是一种通用的算术或逻辑公式表示方法,操作符以中缀形式处于操作数的中间.中缀表达式是人们常用的算术表示方法. 虽然人的大脑很容易理解与分析中缀表达式,但对计算机来说中缀表达式却是很复杂的,因此计算表达式的值时,通常需要先将中缀表达式转换为前缀或后缀表达式,然后再进行求值.对计算机来说,计算前缀或后缀表达式的值要比中缀表达式简单. 比如,计算机计算后缀表达式的过程如下----后缀表达式的计算机求值: 从左

栈的应用:中缀表达式转为后缀表达式

1.中缀表达式转为后缀表达式 规则:(栈实现) 1)如果遇到操作数,我们就直接将其输出. 2)如果遇到操作符,则我们将其放入到栈中,遇到左括号时我们也将其放入栈中. 3)如果遇到一个右括号,则将栈元素弹出,将弹出的操作符输出直到遇到左括号为止.注意,左括号只弹出并不输出. 4)如果遇到任何其他的操作符,如(“+”, “*”,“(”)等,从栈中弹出元素直到遇到发现更低优先级的元素(或者栈为空)为止.弹出完这些元素后,才将遇到的操作符压入到栈中.有一点需要注意,只有在遇到" ) "的情况下

中缀表达式转换为后缀表达式(1042)

描述 中缀表达式是一个通用的算术或逻辑公式表示方法,操作符是以中缀形式处于操作数的中间(例:3 + 4),中缀表达式是人们常用的算术表示方法.后缀表达式不包含括号,运算符放在两个运算对象的后面,所有的计算按运算符出现的顺序,严格从左向右进行(不再考虑运算符的优先规则,如:(2 + 1) * 3 , 即2 1 + 3 *.利用栈结构,将中缀表达式转换为后缀表达式.(测试数据元素为单个字符) input 中缀表达式 output 后缀表达式 样例输入 A+(B-C/D)*E 样例输出 ABCD/-E

数据结构——栈——中缀表达式和后缀表达式

什么是中缀表达式,什么是后缀表达式 我们一般看见的多项式计算都是中缀表达式构成的:1+2*3+4/3 类似这种,为什么说是中缀呢?因为它的计算符号都是在两个数中间的. 那么自然而然的明白了后缀表达式是一种计算符号在两个数后面的. 如123*+43/+ 中缀表达式和后缀表达式有什么关系? 其实仔细你就会发现,上面给出的式子其实都是一样的,只是计算的顺序在后缀表达式中你看不懂而已. 因为我们习惯去看中缀表达式的计算. 其实他们之间是可以互相转换的.他们也可以表达同一个意思,同一个计算式子. 为什么会

将中缀表达式转换为后缀表达式,然后利用栈对表达式求值。

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="js.js"></script> </head> <body> 输入中缀表达式空格分隔 例如 2 + 3 <input type=

Python与数据结构[1] -&gt; 栈/Stack[1] -&gt; 中缀表达式与后缀表达式的转换和计算

中缀表达式与后缀表达式的转换和计算 目录 中缀表达式转换为后缀表达式 后缀表达式的计算 1 中缀表达式转换为后缀表达式 中缀表达式转换为后缀表达式的实现方式为: 依次获取中缀表达式的元素, 若元素为操作数(数字/字母等),则加入后缀表达式中 若元素为操作符,则压入栈中,此时对比入栈操作符与栈内元素的计算等级,等级大于或等于入栈元素的栈内操作符都将被弹出栈,加入到后缀表达式中 左括号直接入栈,优先级最高,不弹出栈内元素 右括号不入栈,而是弹出所有元素加入后缀表达式,直至遇见匹配的左括号,并弹出左括

中缀表达式转为后缀表达式

** * 中缀表达式转后缀表达式 * * 作用:将一长串计算表达式转换为计算机易于操作的字符序列,用于计算器的设计 *  * 参与转换运算符 * +-/*()^% * * * 使用StringBuilder来保存转换出的后缀表达式 * 使用栈来操作运算符 * * * 转换原则 * 1.上述字符中()没有优先级值,+-优先级值为1,/*%优先级值为2,^优先级值为3 * 2.对于一个待计算的表达式,从左向右逐个检查每个字符 * 3.遇到数字,直接append到StringBuilder * 4.遇

ZH奶酪:Python 中缀表达式转换后缀表达式

实现一个可以处理加减乘数运算的中缀表达式转换后缀表达式的程序: 一个输入中缀表达式inOrder 一个输出池pool 一个缓存栈stack 从前至后逐字读取inOrder 首先看一下不包含括号的: (1)操作数:直接输出到pool (2)操作符:判断当前操作符与stack[top]操作符的优先级 <1>当前操作符优先级高于stack[top]:将当前操作符添加到stack中: <2>当前操作符优先级低于或等于stack[top]:从stack[top]开始出栈,直到stack[to

经典白话算法之中缀表达式和后缀表达式

一.后缀表达式求值 后缀表达式也叫逆波兰表达式,其求值过程可以用到栈来辅助存储. 假定待求值的后缀表达式为:6  5  2  3  + 8 * + 3  +  *,则其求值过程如下: (1)遍历表达式,遇到的数字首先放入栈中,依次读入6 5 2 3 此时栈如下所示: (2)接着读到"+",则从栈中弹出3和2,执行3+2,计算结果等于5,并将5压入到栈中. (3)然后读到8(数字入栈),将其直接放入栈中. (4)读到"*",弹出8和5,执行8*5,并将结果40压入栈中