使用堆栈计算后缀表达式--java实现

后缀表达式相对于中缀表达式的优点:

1:不考虑运算优先级和括号。

2:从左到右单次扫描即可,时间复杂度O(1)。

注意:

堆栈是一种计算后缀表达式的理想数据结构,本例中笔者使用了java.util.Stack包,有必要一提的是,java中实现的Stack类由于是从java.util.Vector继承而来,所以它包含了一些从父类继承的方法,因为要凸显栈式结构的实质,所以这里笔者只使用Push,Pop等一般堆栈共有的方法。


基本算法思路:

1:从左到右扫描表达式,依次识别对表达式中每个字符,判断其为操作数还是操作符

2:如果是操作数,则将其压入栈中

3:如果是操作符,则从栈顶弹出两个元素,进行计算后将计算结果重新压入栈中

4:重复上述过程,直至栈中只剩余一个元素,此时表达式也应该到达末尾

注意:为了简化问题,上述过程并没有对表达式是否合法进行判断。


基本过程如图:

使用堆栈计算后缀表达式--java实现_第1张图片


代码实现:

       构造一个PostfixEvaluator类,基本属性有

1::+ - * /   四个char型字符常量

2:java.util.Stack,一个Integer型的堆栈

方法

1:public PostfixEvaluator()

重载构造函数,建立一个空栈

2:private boolean isOperator(String str)

用于判断读入字符是操作数还是操作符

3:private int calculateSingleOp(char operator, int num1, int num2)

根据从栈顶弹出的操作数和操作符计算单个表达式

4:public int evaluate (String str)

读入操作数,压入操作数

读入操作符,弹出两个操作数,并计算

压入计算结果


package com.Stack.PostfixExpression;

import java.util.Stack;
import java.util.StringTokenizer;

/**
 * Demonstrates the use of a stack to evaluate postfix expression
 * @author Wang 
 */
public class PostfixEvaluator {
	
	/**
	 * constants for four calculative symbols
	 */
	private final char ADD = '+';
	private final char SUBTRACT = '-';
	private final char MULTIPLY = '*';
	private final char DIVIDE = '/';
	
	private Stack stack;
	
	/**
	 * Initialize with an empty stack
	 */
	public PostfixEvaluator(){
		stack = new Stack();
	}

	/**
	 * Determines if the specified char is an operator 
	 * @param str
	 * @return boolean is true if it is an operator
	 */
	private boolean isOperator(String str) {

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

	/**
	 * Calculate
	 * @param operator
	 * @param num1
	 * @param num2
	 * @return the calculated result
	 */
	private int calculateSingleOp(char operator, int num1, int num2) {

		int result = 0;
		switch (operator)
		{
		case ADD:
			result = num1 + num2;
			break;		
		case SUBTRACT:
			result = num1 - num2;
			break;
		case MULTIPLY:
			result = num1 * num2;
			break;
		case DIVIDE:
			result = num1 / num2;
			break;
		}
		
		return result;
	}

	/**
	 * Evaluates the specified postfix expression
	 * if an operand is encountered, push it onto the stack.
	 * if an operator is encountered, pop two operand for operator to evaluate
	 * and push the calculated result onto the stack
	 * @param str String representation of a postfix expression
	 * @return integer value of the given expression
	 */
	public int evaluate (String str){

		int num1, num2, result = 0;
		// Temporary vase for every single char
		String token = "";
		StringTokenizer tokenizer = new StringTokenizer(str);
		
		while (tokenizer.hasMoreTokens()){
			// Tokenizer every single char from String
			token = tokenizer.nextToken();
			
			if (isOperator(token)){
				// Transfer Integer object into int
				num2 = (stack.pop()).intValue();
				num1 = (stack.pop()).intValue();
				result = calculateSingleOp(token.charAt(0), num1, num2);
				// Push the calculated result onto the stack
				stack.push(new Integer(result));
			}
			else
			{
				stack.push(new Integer(Integer.parseInt(token)));
			}
		}
		return result;
	}
	
}

测试代码如下:

package com.Stack.PostfixExpression;

import java.util.Scanner;

public class Postfix {

	public static void main(String[] args) {
		String expression = "";
		String again = "";
		int result = 0;

		try {
			@SuppressWarnings("resource")
			Scanner input = new Scanner(System.in);
			do {
				PostfixEvaluator evaluator = new PostfixEvaluator();
				// Read in a valid postfix expression
				System.out
						.println("Please enter a valid postfix expression : ");
				// Assignment
				expression = input.nextLine();

				result = evaluator.evaluate(expression);
				System.out.println();
				System.out
						.println("After evaluating, the calculated result is : "
								+ result);

				// Again
				System.out.println("Do you want to test again? [Y/N]");
				again = input.nextLine();
				System.out.println();
			} while (again.equalsIgnoreCase("Y"));
		}

		catch (Exception IOException) {
			System.out.println("Input exception reported.");
		}
	}
}

测试结果:

使用堆栈计算后缀表达式--java实现_第2张图片


小结:栈式数据结构基本应用

新手上路,难免有不足之处,还请各位看官不吝指正。

你可能感兴趣的:(Java)