中缀表达式转后缀表达式

1. 规则

中缀表达式a + b*c + (d * e + f) * g,其转换成后缀表达式则为a b c * + d e * f  + g * +。

转换过程需要用到栈,具体过程如下:

1)首先入栈一个字符‘#’,在中缀表达式的末尾也添加一个字符‘#’。当两个‘#’相遇时运算完成。

2)如果遇到操作数,我们就直接将其输出。

3)如果表达式中的运算符 > 栈中的运算符,则将操作符入栈。(运算符的优先级如表 1-1)

4)如果表达式中的运算符 < 栈中的运算符,弹出栈中的运算符。执行3

5)如果表达式中的运算符 = 栈中的运算符:若是左括号和右括号相遇,括号里的表达式已运算完成弹出左括号,丢弃右括号。若是两“ # ”相遇,表达式转换完成,退出循环。



2. 实例

下面为输入a + b * c + (d * e + f)*g,处理过程

1)首先读到a,直接输出。

2)读到“+”,将其放入到栈中。

3)读到b,直接输出。

此时栈和输出的情况如下:



4)读到“*”,因为栈顶元素"+"优先级比" * " 低,所以将" * "直接压入栈中。

5)读到c,直接输出。

此时栈和输出情况如下:



6)读到" + ",因为栈顶元素" * "的优先级比它高,所以弹出" * "并输出, 同理,栈中下一个元素" + "优先级大于读到的操作符" + ",所以也要弹出并输出。然后再将读到的" + "压入栈中。

此时栈和输出情况如下:



7)下一个读到的为"(",它优先级最高,所以直接放入到栈中。

8)读到d,将其直接输出。

此时栈和输出情况如下:



9)读到" * ",因为栈中“(”优先级比“*”低,所以直接入栈“*”。

10)读到e,直接输出。

此时栈和输出情况如下:



11)读到" + ",弹出" * "并输出,然后将"+"压入栈中。

12)读到f,直接输出。

此时栈和输出情况:



13)接下来读到“)”,则直接将栈中元素弹出并输出直到遇到"("为止。这里右括号的优先级最低。


14)读到" * ",压入栈中。读到g,直接输出。


15)此时输入数据已经读到末尾,栈中还有两个操作符“*”和" + ",直接弹出并输出。

至此整个转换过程完成。

3.代码

import java.util.Stack;

public class Expression {
	//存放中缀表达式
	private char[] express;
	private int length;
	
	public Expression() {
		express = new char[1000];
		length = 0;
	}
	
	/**
	 * 去除表达式中的空白字符
	 * @param str
	 * @return
	 */
	private boolean StrTrim(String str) {
		//取出表达式首尾空白字符
		str = str.trim();
		if (str.equals("")) {
			return false;
		}
		char[] tmp = str.toCharArray();
		for(int i=0; i<tmp.length; i++) {
			//提取表达式中的非空字符
			if (tmp[i] != ' ') {
				express[length] = tmp[i];
				length++;
			}
		}
		express[length] = '#';
		length++;
		return true;
	}
	/**
	 * 判断stack,exp的优先级
	 * @param stack
	 * @param exp
	 * @return 返回<,=,>或非法退出
	 */
	private char Precede(char stack,char exp) {
		char f = 0;
		switch (exp) {
		case '+':
		case '-':
			if (stack == '(' || stack == '#') 
				f = '<'; //stack<exp
			else 
				f = '>'; //stack>exp
			break;
		case '*':
		case '/':
			if (stack == '*' || stack == '/' || stack == ')') {
				f = '>'; //stack>exp
			}else {
				f = '<'; //stack<exp
			}
			break;
		case '(':
			if (stack == ')') {
				System.out.println("括号不匹配");
				return 0;
			}else {
				f = '<';
			}
			break;
		case ')':
			switch (stack) {
			case '(':
				f = '=';//左右括号相遇(去括号)
				break;
			case '#':
				System.out.println("缺乏右括号1");
				return 0;
			default:
				f = '>';
				break;
			}
			break;
		case '#':
			switch (stack) {
			case '#':
				f = '=';
				break;
			case '(':
				System.out.println("缺乏右括号2");
				return 0;
			default:
				f = '>';
				break;
			}
		}
		return f;
	}
	/**
	 * 判断c是否为7种运算符之一
	 * @param c
	 * @return
	 */
	private boolean IsExp(char c) {
		switch (c) {
		case '+':
		case '-':
		case '*':
		case '/':
		case '(':
		case ')':
		case '#':return true;
		default:return false;
		}
	}
	
	/**
	 * 将中缀表达式转换成后缀表达式
	 * @param mid
	 * @return
	 */
	public char[] Mid2Back(String mid) {
		StrTrim(mid);
		StringBuffer back = new StringBuffer();
		Stack<Character> stack = new Stack<Character>();
		stack.push('#');
		int i = 0;
		char c,s;
		c = express[i++];//将表达式的第一个字符赋给c
		s = stack.peek();
		while (c != '#' || s != '#') {
			if (IsExp(c)) {//c是7种运算符之一
				switch (Precede(s, c)) {
				case '<':
					stack.push(c);//栈中元素的优先权低,入栈c
					if (i < length) {
						c = express[i++];
					}
					break;
				case '=':
					s = stack.pop();
					if (i < length) {
						c = express[i++];
					}
					break;
				case '>':
					back.append(stack.pop());//栈顶的元素优先权高,输出
					break;
				default:
					return null;
				}
			} else {//c不是运算符
				back.append(c);
				if (i < length) {
					c = express[i++];
				}
			}
			s = stack.peek();
		}//while 结束
		return back.toString().toCharArray();
	}
}

测试
public static void main(String[] args) {
	Expression expression = new Expression();
	String str = "a + (d * e + f) * g";
	char[] back = expression.Mid2Back(str);
	System.out.println(back);
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值