本文主要内容:
- 表达式的三种形式
- 中缀表达式与后缀表达式转换算法
一、表达式的三种形式:
- 中缀表达式:运算符放在两个运算对象中间,如:(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)中缀表达式全部读完后,若栈中仍有运算符,将其送到输出队列中。
举例:
上图中,左侧的那一列为输出序列,右侧的那一列为栈。
2、运用后缀表达式进行计算:
(1)建立一个栈S;
(2)从左到右读后缀表达式,读到数字就将它转换为数值压入栈S中,读到运算符则从栈中依次弹出两个数分别到Y和X,然后以“X 运算符 Y”的形式计算机出结果,再压加栈S中;
(3)如果后缀表达式未读完,就重复上面过程,最后输出栈顶的数值则为结束。
举例:
3+(2-5)*6/3=-3 ,其后缀表达式为:325-6*3/+。其运算结果如下:
代码实现:
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
}
}