栈的应用--中缀表达式转换为后缀表达式&逆波兰计算器的实现

首先是栈的实现:

定义接口:

<span style="font-size:18px;">package day4;

/**
 * @author cby
 * @version 创建时间:2014-11-12 上午11:51:03 类说明
 * @param <T>
 */
public interface MyStack<T> {

	void push(T data);

	T pop();

	void print();

	int getSize();

	void clear();

	boolean isEmpty();
}</span>
编写类实现接口:
<span style="font-size:18px;">package day4;

/**
 * @author cby
 * @version 创建时间:2014-11-12 上午11:52:51 类说明
 * @param <T>
 */
public class MyLinkedStack<T> implements MyStack<T> {

	int size;
	Node<T> top;

	public MyLinkedStack() {
		super();
		size = 0;
		top = null;
	}

	@Override
	public void push(T data) {
		Node<T> node = new Node<T>();
		node.data = data;
		node.pre = top;
		top = node;
		size++;
	}

	@Override
	public T pop() {
		Node<T> node = top;
		top = top.pre;
		size--;
		return node.data;
	}

	public T firstData() {
		return top.data;
	}

	@Override
	public void print() {
		Node<T> node = top;
		while (node != null) {
			System.out.print(node.data + "  ");
			node = node.pre;
		}
		System.out.println();
	}

	@Override
	public int getSize() {
		return size;
	}

	@Override
	public void clear() {
		top = null;
		size = 0;
	}

	@Override
	public boolean isEmpty() {
		return size == 0;
	}

}
</span>
下面是核心代码:

中缀表达式转换为后缀表达式&逆波兰计算器的实现

<span style="font-size:18px;">package day4;

import java.util.regex.Pattern;

import javax.swing.plaf.TextUI;

import org.apache.http.util.TextUtils;

/**
 * @author cyb
 * @version 创建时间:2014-11-12 下午12:26:25 类说明
 */
public class Test {

	public static void main(String[] args) {
		System.err.println("1 1 2 + 3 * * 3 2 / 3 * + 2.5 +");
		System.out
				.println(niBoLan("1 1 2 + 3 * * 3 2 / 3 * + 2.5 +".split(" ")));
		// String string =
		// "1 * ( 1 + 2 ) * 3 + 3 / 2 / 2 * 2 * 2 / 2 * 3 + 2.5";
		String string = "2 /   0      /    4";
		System.out.println(transformForm(getMyStr(string)));
		System.out.println(niBoLan(transformForm(getMyStr(string)).split(" ")));
	}

	/**
	 * 格式化输入字符串
	 */
	private static String getMyStr(String string) {
		StringBuffer buffer = new StringBuffer();
		String[] temp = string.trim().split(" ");
		for (int i = 0; i < temp.length; i++) {
			if (TextUtils.isBlank(temp[i]) || TextUtils.isEmpty(temp[i])) {
			} else {
				buffer.append(temp[i] + " ");
			}
		}

		return buffer.toString();
	}

	/**
	 * 逆波兰计算器
	 */
	public static double niBoLan(String[] str) {
		MyLinkedStack<String> linkedStack1 = new MyLinkedStack<>();
		for (int i = 0; i < str.length; i++) {
			String curr = str[i];
			if (curr.equals("+")) {
				double a = Double.parseDouble(linkedStack1.pop());
				double b = Double.parseDouble(linkedStack1.pop());
				linkedStack1.push((a + b) + "");
			} else if (curr.equals("-")) {
				double a = Double.parseDouble(linkedStack1.pop());
				double b = Double.parseDouble(linkedStack1.pop());
				linkedStack1.push((b - a) + "");
			} else if (curr.equals("*")) {
				double a = Double.parseDouble(linkedStack1.pop());
				double b = Double.parseDouble(linkedStack1.pop());
				linkedStack1.push((a * b) + "");
			} else if (curr.equals("/")) {
				double a = Double.parseDouble(linkedStack1.pop());
				double b = Double.parseDouble(linkedStack1.pop());
				linkedStack1.push((b / a) + "");
			} else {
				linkedStack1.push(curr);
			}
		}
		return Double.parseDouble(linkedStack1.pop());
	}

	/**
	 * 中缀表达式转换为后缀表达式
	 */
	public static String transformForm(String normal) {
		String[] str = normal.split(" ");
		MyLinkedStack<String> linkedStack = new MyLinkedStack<>();
		StringBuffer buffer = new StringBuffer();
		String temp = "";
		for (int i = 0; i < str.length; i++) {
			if (str[i] == " ") {
				continue;
			}
			if (isNumeric(str[i])) {// 数字直接输出
				buffer.append(str[i] + " ");
			} else { // "("和")"
				if ("(".equals(str[i])) {// 左括号直接入栈
					linkedStack.push(str[i]);
				} else if (")".equals(str[i])) {// 遇到右括号,将栈中左括号上面的符号输出
					while (!(temp = linkedStack.pop()).equals("(")) {
						buffer.append(temp + " ");
					}
				} else {// "+" "-" "*" "/"
					if ("+".equals(str[i]) || "-".equals(str[i])) {// 遇到加减符号,将栈中符号全部输出,然后这个加减符号入栈
						if (linkedStack.getSize() > 0) {
							temp = linkedStack.firstData();
							while (!linkedStack.isEmpty()
									&& ("+".equals(temp) || "-".equals(temp)
											|| "*".equals(temp) || "/"
												.equals(temp))) {
								temp = linkedStack.pop();
								buffer.append(temp + " ");
							}
						}
						linkedStack.push(str[i]);
					} else if ("*".equals(str[i]) || "/".equals(str[i])) {
						/**
						 * 2 / 3 / 4 连除而且两除号之间是数字时 2 / 3 * 4 一除一乘而且两符号之间是数字时
						 * 当出现以上两种组合组合时,做以下特殊处理
						 **/
						if ("/".equals(str[i])
								&& i < str.length - 2
								&& isNumeric(str[i + 1])
								&& ("/".equals(str[i + 2]) || "*"
										.equals(str[i + 2]))) {
							buffer.append(str[i + 1] + " ");
							buffer.append(str[i] + " ");
							i = i + 1;
						} else {
							linkedStack.push(str[i]);
						}
					}
				}
			}
		}
		temp = linkedStack.firstData();// 最后将栈中的符号全部输出
		while (!linkedStack.isEmpty()
				&& ("+".equals(temp) || "-".equals(temp) || "*".equals(temp) || "/"
						.equals(temp))) {
			temp = linkedStack.pop();
			buffer.append(temp + " ");
		}
		return buffer.toString();
	}

	public static boolean isNumeric(String str) {
		Pattern pattern = Pattern.compile("[0-9]\\d*\\.?\\d*");
		return pattern.matcher(str).matches();
	}
}
</span>



你可能感兴趣的:(逆波兰表达式)