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

本文主要内容:

  • 表达式的三种形式
  • 中缀表达式与后缀表达式转换算法

一、表达式的三种形式:

  • 中缀表达式:运算符放在两个运算对象中间,如:(2+1)*3。我们从小做数学题时,一直使用的就是中缀表达式。
  • 后缀表达式:不包含括号,运算符放在两个运算对象的后面,所有的计算按运算符出现的顺序,严格从左向右进行(不再考虑运算符的优先规则),如:2 1 + 3 *。又比如3+(6-4/2)*5=23的后缀表达式为:3642/-5*+# (#符号为结束符)
  • 前缀表达式:同后缀表达式一样,不包含括号,运算符放在两个运算对象的前面,如:* + 2 1 3 。前缀表达式和后缀表达式其实是差不多的,只不过符号位置不同而已,前缀表达式不是很常见。

 

二、中缀表达式转换为后缀表达式:(思路)

1、将中缀表达式转换为后缀表达式:(步骤,有点难理解)

(1)当读到数字直接送至输出队列中;

(2)当读到运算符t时:

  a.将栈中所有优先级高于或等于t的运算符弹出,送到输出队列中;

    注:这句话不好理解,可以说成这样,从栈顶开始,依次弹出比当前处理的运算符优先级高的运算符,直到一个比它优先级低的或者遇到了一个左括号就停止

  b.t进栈;

(3)读到左括号时总是将它压入栈中;

(4)读到右括号时,将靠近栈顶的第一个左括号上面的运算符全部依次弹出,送至输出队列后,再丢弃左括号;

(5)中缀表达式全部读完后,若栈中仍有运算符,将其送到输出队列中。

 

举例:

124b3dd7-f3b3-4110-904c-8a2b1d85dccd

上图中,左侧的那一列为输出序列,右侧的那一列为栈。

2、运用后缀表达式进行计算:

  (1)建立一个栈S;

  (2)从左到右读后缀表达式,读到数字就将它转换为数值压入栈S中,读到运算符则从栈中依次弹出两个数分别到Y和X,然后以“X 运算符 Y”的形式计算机出结果,再压加栈S中;

  (3)如果后缀表达式未读完,就重复上面过程,最后输出栈顶的数值则为结束。

举例:

3+(2-5)*6/3=-3 ,其后缀表达式为:325-6*3/+。其运算结果如下:

45270e43-7c61-4ac2-af8f-efb437e8d742

代码实现:

public class PrintTree {

	/**
	 * 计算后缀表达式的值
	 * @param exp
	 * @return
	 */
	public static int giveResult(String exp){
		Stack<Integer> stack = new Stack<Integer>();
		int length = exp.length();
		int index = 0;
		while(index < length){
			switch(exp.charAt(index)){
				case '0':
				case '1':
				case '2':
				case '3':
				case '4':
				case '5':
				case '6':
				case '7':
				case '8':
				case '9':
					stack.push((int) exp.charAt(index) - 48);
					break;
				case '+':
					int a = stack.pop();
					int b = stack.pop();
					stack.push(a + b);
					break;
				case '-':
					int c = stack.pop();
					int d = stack.pop();
					stack.push(d - c);
					break;
				case '*':
					int e = stack.pop();
					int f = stack.pop();
					stack.push(e * f);
					break;
				case '/':
					int g = stack.pop();
					int h = stack.pop();
					stack.push(h / g);
					break;
			}
			index++;
		}
		return stack.pop();
	}
	
	/**
	 * 中缀转后缀
	 * @param exp
	 */
	public static String infixToPostfix(String exp){
		Stack<Character> stack = new Stack<Character>();
		String suffix = "";
		int index = 0;
		int length = exp.length();
		while(index < length){
			switch(exp.charAt(index)){
				case '0':
				case '1':
				case '2':
				case '3':
				case '4':
				case '5':
				case '6':
				case '7':
				case '8':
				case '9':
					suffix += exp.charAt(index);
					break;
				case '*':
				case '/':
					stack.push(exp.charAt(index));
					break;
				case '(':
					stack.push(exp.charAt(index));
					break;
				case '+':				// 碰到'+''-',将栈中所有运算符弹出,送到输出队列中
				case '-':
					while (stack.size() != 0) {
						 char temp = stack.pop();
						 if (temp == '(') {
						     stack.push('(');
						     break;
						 }
						 suffix += temp;
					}
					stack.push(exp.charAt(index));
					break;
				case ')':
					while(!stack.isEmpty() && stack.peek() != '('){
						suffix += stack.pop();
					}
					stack.pop();
					break;
				
			}
			index++;
		}
		while(!stack.isEmpty()){
			suffix += stack.pop();
		}
		return suffix;
	}
	
	public static void main(String[] args) {
		int result = giveResult(infixToPostfix("3+(5-2)*6/3"));
		System.out.println(result);//9
	}

}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值