java 逆波兰表达式

最近想把这破机 装成WIN7 想想还是算了 ...  反正用的机会也不多。

不过 发现了一些 想念的东西

从前的作业.

从前的记忆.


package org.lmz;

import java.util.Queue;
import java.util.Scanner;
import java.util.Stack;
import java.util.concurrent.LinkedBlockingQueue;

public class calculator_test {

	static String operator = "+-*/%^()";

	/**
	 * 预处理表达式,正、负号前加0(如果一个加号(减号)出现在最前面或左括号后面,则该加号(减号)为正负号)  比如  -1-(-1+1) 这种表达式 会处理成 0-1-(0-1+1)
	 */
	public static String pretreatment(String str) {
		StringBuffer sb = new StringBuffer(str);
		for (int i = 0; i < sb.length(); i++) {
			char c = sb.charAt(i);
			if (operator.indexOf(c) >= 0) {
				if (i == 0) {
					sb.insert(0, '0');
					i++;
				} else if (sb.charAt(i - 1) == '(') {
					sb.insert(i, '0');
					i++;
				}
			}
		}
		return sb.toString();
	}

	/***
	 * 0 优先级相等 ; -1 op1 优先级大于op2; 1 op2 优先级大于 op1
	 */
	public static int opcompare(char op1, char op2) {
		if (op1 == '(') { // 遇到括号 就直接入栈 所以 op2 大
			return 1;
		}
		if ('^' == op1) {
			if (op2 == '^') {
				return 0;
			}
			return -1;
		} else if ("+-".indexOf(op1) >= 0) {
			if ("+-".indexOf(op2) >= 0) {
				return 0;
			}
			return 1;
		} else // if("*/%".indexOf(op1) >=0) 没必要 再判断是否为 */% 了
		{
			if ("+-".indexOf(op2) >= 0) {
				return -1;
			} else if ('^' == op2) {
				return 1;
			}
			return 0;
		}
	}
	/**
	 * 计算传入的算术表达式 
	 */
	public static double Calculator2(String s) throws Exception {
		//预处理式子
		String prestr = pretreatment(s);
		//用于保存  逆波兰式 的队列 
		LinkedBlockingQueue<String> polish = new LinkedBlockingQueue<String>();
		// 拼接 数字 char ---> numble
		StringBuffer temp = new StringBuffer();
		
		Stack<Character> stack = new Stack<Character>();
		for (int i = 0; i < prestr.length(); i++) {

			char c = prestr.charAt(i);
			//如果找到 操作符
			if (operator.indexOf(c) >= 0) {
				if (temp.length() > 0) {//如果 有数字 就压栈
					polish.offer(temp.toString());
					temp = new StringBuffer();
				}
				switch (c) {
				case '(':
					stack.push(c);
					break;
				case ')':
					while (stack.size() > 0) {
						char op = stack.pop();
						if (op != '(') {
							polish.offer(String.valueOf(op));
						} else {
							break;
						}
					}
					break;
				default:
					if (stack.size() == 0) {
						stack.push(c);
					} else {
						while (stack.size() > 0) {
							char op1 = stack.lastElement();
							int com = opcompare(op1, c);
							if (com <= 0) {
								polish.offer(String.valueOf(stack.pop()));
							} else {
								stack.push(c);
								break;
							}
						}
						if (stack.size() == 0) {
							stack.push(c);
						}
					}
					break;
				}
			} else {
				temp.append(c);
			}
		}
		if (temp.length() > 0) {
			polish.offer(temp.toString());
		}
		while (stack.size() > 0) {
			polish.offer(String.valueOf(stack.pop()));
		}
		System.out.println("Calcstra Queue:" + polish.toString());

		return CalcstraWithQueue(polish);
	}
	/**
	 *  计算 逆波兰表达式  用队列表示
	 * @throws Exception  各种错误都有可能
	 */
	public static double CalcstraWithQueue(Queue<String> que) throws Exception {
		Stack<Double> stack = new Stack<Double>();
		while(true)
		{
		String str = que.poll();
		if(str == null)
		{
			break;
		}
		if (operator.indexOf(str) >= 0) {
			
			double num2 = stack.pop();
			double num1 = stack.pop();
			double tempresult = 0;
			switch (str.charAt(0)) {
			case '+':
				tempresult = num1 + num2;
				break;
			case '-':
				tempresult = num1 - num2;
				break;
			case '*':
				tempresult = num1 * num2;
				break;
			case '/':
				if(num2 == 0)
				{
					throw new Exception("出错:除数为 0");
				}
				tempresult = num1 / num2;
				break;
			case '%':
				tempresult = num1 % num2;
				break;
			case '^':
				tempresult = Math.pow(num1, num2);
				break;
			default:
				throw new Exception("运算符: " + str + " 未识别!");
			}
			stack.push(tempresult);
		} else {
			stack.push(Double.valueOf(str));
		}
		}
		return stack.pop();
	}
	public static void main(String[] args) {

		Scanner reader = new Scanner(System.in);
		while(true)
		{
		String s = reader.nextLine();
		double result = 0;
		try {
			result = Calculator2(s);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println(result);
		}
	}
}



原文地址:https://www.cnblogs.com/jiangu66/p/3177617.html