【Java数据结构的实现】之系列三栈的实现(使用栈计算后缀表达式)

原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://enetq.blog.51cto.com/479739/713534

【Java数据结构的实现】之系列三栈的实现(使用栈计算后缀表达式)

上讲介绍了栈的介绍,最后并给出了栈的抽象数据类型

1.1本章学习目标

  • 中、后缀表达式简介
  • 后缀表达式的实现

本文介绍了栈的实例--使用栈计算后缀表达式:

1.2 中、后缀表达式简介

①中缀表达式:

       通常,算术表达式写作中缀表达式,,什么是中缀表达式呢?中缀表达式就是:操作符位于操作数之间。

如下形式:

<操作数><操作符><操作数>

例如表达式:1+2*3,计算时,我们根据表达式的优先规则来计算。其结果是7而不是9.

那什么是后缀表达式呢?

②后缀表达式:

后缀表达式就是:操作符位于两个操作数之后,后缀表达式的形式如下:

<操作数><操作数><操作符>

如下所示:

 

 
  
  1. 1 2 - 等价于1-2  
  2.  

③使用后缀表达式的优点:

      后缀表达式比中缀表达式更容易计算,因为它不用考虑优先规则和括弧,表达式中的操作数和操作符的顺序就足以完成计算。

因此程序设计语言编辑器和运行时环境在其内部中往往使用后缀表达式。

④后缀表达式的计算规则:

        后缀表达式的计算过程可以概括如下:

从左到右扫描整个表达式,把每个操作符应用到其之前两个相邻的操作数,并计算该结果,剩下的表达式以此类推。

1+2*3

可以转换成后缀表达式如下:

1 2 3 * +

计算过程如下:

1 2*3 + --> 1 6 + -->7

更复杂的后缀表达式,亦是如此规则。由此可以发现,栈是用于计算后缀表达式的理想数据结构。

1.3 后缀表达式的实现

①程序设计的思路:

 
  
  1. /**  
  2.      * 从左到右扫描表达式,以此标识出每个符号(操作数或操作符)。如果是操作数,  
  3.      * 则把它压入栈中。如果是操作符,则从栈中弹出两个元素,  
  4.      * 并把该操作符应用在这两个元素只上,然后把操作结果压入栈中。  
  5.      * 当到达表达式的末尾时,栈中所神域的元素就是该表达式的计算结果。  
  6.      * @param expr 后缀表达式  
  7.      * @return int 后缀表达式的值  
  8.      * */ 


后缀表达式又称为逆波兰表达式。



class PostfixEvaluator {
	private final char ADD = '+';
	private final char SUB = '-';
	private final char MUL = '*';
	private final char DIV = '/';
	private Stack stack;

	public PostfixEvaluator() {
		stack = new Stack();
	}

	// 后缀表达式:3 2 2 * + 1 -
	// 中缀表达式:3 + 2 * 2 - 1
	public int evaluate(String expr) {
		// 将字符串分解,\s 匹配任何空白字符,包括空格、制表符、换页符等。
		String[] tokenizer = expr.split("\\s");
		for (int i = 0; i < tokenizer.length; i++) {
			String token = tokenizer[i].trim();
			
			if (isOperator(token)) { // 判断是操作符,则出栈两个操作数
				int op2 = (stack.pop()).intValue();
				int op1 = (stack.pop()).intValue();
				char operator = token.charAt(0); // 提取操作符+、-、*、/
				
				stack.push(calc(operator, op1, op2)); // 把计算结果压入栈中
			} else {
				stack.push(Integer.parseInt(token)); // 压入操作数
			}
		}
		
		return stack.pop(); // 将最后的计算结果返回
	}

	private int calc(char operation, int op1, int op2) {
		int result = 0;
		switch (operation) {
		case ADD:
			result = op1 + op2;
			break;
		case SUB:
			result = op1 - op2;
			break;
		case MUL:
			result = op1 * op2;
			break;
		case DIV:
			result = op1 / op2;
			break;
		}
		return result;
	}

	private boolean isOperator(String token) {

		return (token.equals("+") || token.equals("-") || token.equals("*") || token
				.equals("/"));
	}
}

public class Ope {
	public static void main(String[] args) {
		String expression = "3 2 2 * + 1 -";
		PostfixEvaluator evaluator = new PostfixEvaluator();

		int result = evaluator.evaluate(expression);
		System.out.println("计算结果为:" + result);
	}
}

//------------------------------------------------------------------------------------------------

总结:自己在做这个后缀表达式的时候没有啥思路,原因其实也很简单,对原理不清楚。

写程序的时候,一个知识环境没有,所以写起来一点思路也没有。这里要知道中缀表达式和后缀表达式,

它们如何形成的,又如何利用后缀表达式进行计算的。

(1)后缀表达式,利用栈来保存“操作数”,当遇到“操作符”时弹出栈中的“操作数”,并把计算结果压入栈中,下次计算的时候还需要利用上次的计算结果进行计算。

你可能感兴趣的:(算法与数据结构)