java中缀表达式转后缀表达式

原创 2015年06月08日 14:09:17
将中缀表达式转换为后缀表达式
与转换为前缀表达式相似,遵循以下步骤:
(1) 初始化两个栈:运算符栈S1和储存中间结果的栈S2;
(2) 从左至右扫描中缀表达式;
(3) 遇到操作数时,将其压入S2;
(4) 遇到运算符时,比较其与S1栈顶运算符的优先级:
(4-1) 如果S1为空,或栈顶运算符为左括号“(”,则直接将此运算符入栈;
(4-2) 否则,若优先级比栈顶运算符的高,也将运算符压入S1(注意转换为前缀表达式时是优先级较高或相同,而这里则不包括相同的情况);
(4-3) 否则,将S1栈顶的运算符弹出并压入到S2中,再次转到(4-1)与S1中新的栈顶运算符相比较;
(5) 遇到括号时:
(5-1) 如果是左括号“(”,则直接压入S1;
(5-2) 如果是右括号“)”,则依次弹出S1栈顶的运算符,并压入S2,直到遇到左括号为止,此时将这一对括号丢弃;
(6) 重复步骤(2)至(5),直到表达式的最右边;
(7) 将S1中剩余的运算符依次弹出并压入S2;

(8) 依次弹出S2中的元素并输出,结果的逆序即为中缀表达式对应的后缀表达式(转换为前缀表达式时不用逆序)。

import java.util.Stack;

public class Calculator {

	public static void main(String[] args) {
		suffixCalc("1+((2+3)*4)-5");
	}
	public static void suffixCalc(String input) {
		Stack<Double> numbersStack = new Stack<Double>();
		Stack<Character> operatorsStack = new Stack<Character>();
		Stack<Object> suffixExpr = new Stack<Object>();
		int len = input.length();
		char c, temp;
		double number;
		for (int i = 0; i < len; i++) {
			c = input.charAt(i);
			if (Character.isDigit(c)) {
				int endDigitPos = getEndPosOfDigit(input, i);
				number = Double.parseDouble(input.substring(i, endDigitPos));
				i = endDigitPos - 1;
				numbersStack.push(number);
				if ((int)number == number) {
					suffixExpr.push((int)number);
				} else {
					suffixExpr.push(number);
				}
			} else if (isOperator(c)) {
				// 操作符栈非空,且栈顶不是'(',且当前操作符优先级低于栈顶操作符
				while (!operatorsStack.isEmpty() 
						&& operatorsStack.peek() != '(' 
						&& priorityCompare(c, operatorsStack.peek()) <= 0) {
					suffixExpr.push(operatorsStack.peek());
					numbersStack.push(calc(numbersStack, operatorsStack.pop()));
				}
				operatorsStack.push(c);
			} else if (c == '(') {
				operatorsStack.push(c);
			} else if (c == ')') {
				while ((temp = operatorsStack.pop()) != '(') {
					numbersStack.push(calc(numbersStack, temp));
					suffixExpr.push(temp);
				}
			} else if (c == ' ') {
				
			} else {
				throw new IllegalArgumentException("wrong character '" + c + "'");
			}
		}
		
		while (!operatorsStack.isEmpty()) {
			temp = operatorsStack.pop();
			suffixExpr.push(temp);
			numbersStack.push(calc(numbersStack, temp));
		}
		
		printStack(suffixExpr);
		System.out.println("\ncalc result\t" + numbersStack.pop());
	}
	
	private static void printStack(Stack<?> stack) {
		String s = "";
		while (!stack.isEmpty()) {
			s += stack.pop();
		}
		for (int i = s.length()-1; i >= 0; i--) {
			System.out.print(s.charAt(i)+" ");
		}
	}

	private static int getEndPosOfDigit(String input, int start) {
		char c;
		int end = start + 1;
		for (int i = start + 1; i < input.length(); i++) {
			c = input.charAt(i);
			if (Character.isDigit(c) || c == '.') {
				continue;
			} else {
				end = i;
				break;
			}
		}
		return end;
	}

	private static boolean isOperator(char c) {
		return (c == '+' || c == '-' || c == '*' || c == '/');
	}

	// op1优先级高于op2 return 1
	private static int priorityCompare(char op1, char op2) {
		switch (op1) {
		case '+':
		case '-':
			return (op2 == '*' || op2 == '/' ? -1 : 0);
		case '*':
		case '/':
			return (op2 == '+' || op2 == '-' ? 1 : 0);
		}
		return 1;
	}

	private static double calc(Stack<Double> numbersStack, char op) {
		double num1 = numbersStack.pop();
		double num2 = numbersStack.pop();
		return calc(num2, num1, op);
	} 
	private static double calc(double num1, double num2, char op) throws IllegalArgumentException {
		switch (op) {
		case '+':
			return num1 + num2;
		case '-':
			return num1 - num2;
		case '*':
			return num1 * num2;
		case '/':
			if (num2 == 0)
				throw new IllegalArgumentException("divisor can't be 0.");
			return num1 / num2;
		default:
			return 0;
		}
	}
}

output:

1 2 3 + 4 * + 5 - 
calc result 16.0

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

java中使用栈将中缀表达式转化为后缀表达式

中缀表达式:5*(((9*8+5)*(4+6))+7),即中缀表达式就是我们

中缀表达式转成后缀表达式(含java实现的具体代码)

已转到:http://www.wypblog.com/archives/161             后缀表达式又叫做逆波兰表达式。在通常的表达式中,二元运算符总是置于与之相关的...

java将中缀表达式转为后缀表达式

参考自:http://blog.sina.com.cn/s/blog_6047c8870100qapb.html package com.lmiky.test; import java...

Java实现中缀表达式转后缀表达式并计算结果

栈中缀表达式就是形如a(b-c)+d*这样我们平常写的式子,如果按平时逻辑上的处理顺序的话计算机比较难正确处理,因为运算符之间有优先级,括号的优先级比乘除高,乘除的优先级比加减高,这是小学的知识。 ...
  • dgeek
  • dgeek
  • 2017-03-19 13:54
  • 1444

java实现中缀表达式转后缀表达式并且计算

自己写一个栈 用数组实现package cn.itcast.StackAndQuen; import java.util.ArrayList; import java.util.List; impo...

java算术表达式求值-中缀表达式转后缀表达式

Java中可以利用双栈算法实现算术表达式求值,下面结合代码讲解简单和复杂两种情况1、简单的算术表达式:(((3-1)*2)+3)主要思想: (1)利用两个栈,一个栈存储数字,一个栈存储符号(2)符号...

java实现中缀转后缀,后缀计算值

本文主要内容: 表达式的三种形式中缀表达式与后缀表达式转换算法 一、表达式的三种形式: 中缀表达式:运算符放在两个运算对象中间,如:(2+1)*3。我们从小做数学题时,一直使用的就是...

中缀表达式转换为前缀及后缀表达式并求值(java实现)

转载自:http://www.java3z.com/cwbwebhome/article/article8/83542.html?id=4612 它们都是对表达式的记法,因此也被称为前缀记法、中缀记法...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)