(注:日志类 Log 详见 http://blog.csdn.net/runninglion/article/details/46057643)
一. 栈的抽象数据类型定义
package listset;
public interface StackADT<T> {
public void push(T item);
public T pop();
public T peek(); // get the top item but not pop
public boolean isEmpty();
public int size();
public String toString();
}
二. 简单的 ArrayStack 的实现
1. ArrayStack 类定义
package arrayset;
import listset.StackADT;
import util.Log;
public class ArrayStack<T> implements StackADT<T>{
private static final String LOG_TAG = ArrayStack.class.getName();
private final int DEF_CAPACITY = 5;
private int mTop;
private T[] mStack;
@SuppressWarnings("unchecked")
public ArrayStack() {
mTop = 0;
mStack = (T[])(new Object[DEF_CAPACITY]);
}
@SuppressWarnings("unchecked")
public ArrayStack(int capacity) {
mTop = 0;
mStack = (T[])(new Object[capacity]);
}
@Override
public void push(T item) {
if(size() == mStack.length) {
Log.debug(LOG_TAG, "push()", "stack full, stack length = " +
mStack.length + ", expandCapacity() is called");
expandCapacity();
}
mStack[mTop] = item;
mTop++;
}
@SuppressWarnings("unchecked")
private void expandCapacity() {
T[] larger = (T[])(new Object[mStack.length * 2]);
for(int index = 0; index < mStack.length; index++) {
larger[index] = mStack[index];
}
mStack = larger;
}
@Override
public T pop() {
if(isEmpty()) {
Log.error(LOG_TAG, "pop()", "try to pop from a empty stack");
return null;
}
mTop--;
T ret = mStack[mTop];
mStack[mTop] = null;
return ret;
}
@Override
public T peek() {
if(isEmpty()) {
Log.error(LOG_TAG, "peek()", "try to peek from a empty stack");
return null;
}
return mStack[mTop - 1];
}
@Override
public boolean isEmpty() {
return 0 == mTop;
}
@Override
public int size() {
return mTop;
}
}
注:其实在 pop() 操作的时候,可以根据各种策略,决定是不是该减小 stack 的空间,这里就不讨论了 ...
2. ArrayStack 类的测试类 MainArrayStack
package arrayset;
public class MainArrayStack {
public static void main(String[] args) {
int counter = 0;
ArrayStack<Integer> stack = new ArrayStack<Integer>();
for(counter = 0 ; counter < 20; counter++) {
stack.push(new Integer(counter));
}
for(counter = 0; counter < 25; counter++) {
stack.pop();
}
for(counter = 0 ; counter < 3; counter++) {
stack.push(new Integer(counter));
}
for(counter = 0; counter < 5; counter++) {
stack.pop();
}
}
}
三. 利用 ListStack 实现的后缀表达式求值
1. ListStack 的实现
package expression;
import java.util.ArrayList;
import java.util.List;
import listset.StackADT;
import util.Log;
public class ListStack<T> implements StackADT<T> {
private static final String LOG_TAG = ListStack.class.getName();
List<T> mList;
public ListStack() {
mList = new ArrayList<T>();
}
@Override
public void push(T item) {
Log.debug(LOG_TAG, "push()", "push operation");
mList.add((T) item);
}
@Override
public T pop() {
Log.debug(LOG_TAG, "pop()", "pop operation");
if(0 == mList.size()) {
Log.error(LOG_TAG, "pop()", "the mList is empty!");
return null;
}
T obj = mList.get(mList.size() - 1);
mList.remove(mList.size() - 1);
return obj;
}
@Override
public T peek() {
Log.debug(LOG_TAG, "peek()", "peek operation");
if(0 == mList.size()) {
Log.error(LOG_TAG, "peek()", "the mList is empty!");
return null;
}
return mList.get(mList.size() - 1);
}
@Override
public boolean isEmpty() {
return 0 == mList.size();
}
@Override
public int size() {
return mList.size();
}
}
2. 后缀表达式 PostfixEvaluator 类的定义
package expression;
import java.util.StringTokenizer;
public class PostfixEvaluator {
private final char ADD = '+';
private final char SUBTRACT = '-';
private final char MULTIPLY = '*';
private final char DIVIDE = '/';
private ListStack<Integer> mStack;
public PostfixEvaluator() {
mStack = new ListStack<Integer>();
}
public int evaluate(String expr) {
int op1, op2, result = 0;
String token;
// the default separator are space、\t、\n、\r
StringTokenizer tokenizer = new StringTokenizer(expr);
while(tokenizer.hasMoreElements()) {
token = tokenizer.nextToken();
if(isOperator(token)) {
op2 = ((Integer) mStack.pop()).intValue();
op1 = ((Integer) mStack.pop()).intValue();
result = evalSingleOp(token.charAt(0), op1, op2);
mStack.push(new Integer(result));
} else {
mStack.push(new Integer(Integer.parseInt(token)));
}
}
return result;
}
private boolean isOperator(String str) {
return (str.equals("+")
|| str.equals("-")
|| str.equals("*")
|| str.equals("/"));
}
private int evalSingleOp(char operation, int op1, int op2) {
int result = 0;
switch(operation) {
case ADD: {
result = op1 + op2;
break;
}
case SUBTRACT: {
result = op1 - op2;
break;
}
case MULTIPLY: {
result = op1 * op2;
break;
}
case DIVIDE: {
result = op1 / op2;
break;
}
}
return result;
}
}
3. 测试类 MainPostfix
package expression;
import java.util.Scanner;
public class MainPostfix {
public static void main(String[] args) {
String expression, again;
int result;
try {
Scanner in = new Scanner(System.in);
do {
PostfixEvaluator evaluator = new PostfixEvaluator();
System.out.println("Enter a valid postfix expression:");
expression = in.nextLine();
result = evaluator.evaluate(expression);
System.out.println();
System.out.println("That expression equals " + result);
System.out.print("Evaluate another expression [Y/N] ?");
again = in.nextLine();
System.out.println();
} while (again.equals("y") || again.equals("Y"));
in.close();
} catch(Exception e) {
System.out.println("MainPostfix : error, Input exception reported.");
e.printStackTrace();
}
}
}