对于一个算术表达式,我们可以用栈这种数据结构来计算它的值,也就是说可以将一个标准形式的表达式(或叫中缀表达式)转换成后缀表达式,并坚持普通的优先级法则,将一般问题浓缩成小规模问题,我们假设有运算符 + - * / ( )中缀表达式是合法的,比如 :a + b * c + ( d * e + f ) * g 转换成后缀表达式 a b c * + d e * f + g * + ,对表达式进行遍历,当读到数字字符时,把它添加到后缀表达式中,当第一次读到运算符时,将它入栈,如果栈顶元素的的优先级高于后面读到的运算符的优先级时,则该运算符入栈,否则将栈顶元素出栈。为了理解这种机制,我们把上述中缀表达式转换成后缀表达式。
首先,a被读入,把它添加到后缀表达式中,然后读到 + ,将它入栈,接着b读入并添加到后缀表达式中,然后读到 * ,此时栈顶元素是+,优先级低于*,所以将 * 入栈,接着c读入并输出到后缀表达式中。然后又读到 + , 此时我们检查一下栈,需要将 * 弹出放到后缀中,栈顶元素变成了 + ,不高于刚读到的 + ,所以将栈顶元素 + 弹出到后缀中,并将刚读到的 + 放到栈顶,此时的后缀表达式是 : a b c * + .下一个读到的的符号是 ( ,由于具有最高的优先级,所以它入栈,然后 d读入并输出到后缀中。继续进行,我们又读到 * 除非正在处理右括号 ) ,否则左括号 ( 不会从栈中弹出,所以 * 没有弹出,下一个是 e ,它被读入并输出到后缀中,。此时的后缀表达式是a b c * + d e.再往后读到 + 我们栈顶元素 * 弹出,然后将 + 入栈,然后我们读到 f 并输出到后缀中。接下来我们读到 ) 因此将栈顶元素直到 ( ,此时后缀表达式为 a b c * + d e * f + 下面又读到 * 该运算符入栈,最后g被读入并输出到后缀中。现在中缀表达式已经被遍历完了,我们将栈中所有元素弹出,直到栈变为空栈。最后后缀表达式为a b c * + d e * f + g * + 这样就得到了我们需要的结果了。下面在Java代码中实现具体的过程(myString为中缀表达式,suffixExpression为后缀表达式,集合list实现栈的结构)。
</pre><pre name="code" class="java">for(int i =0;i<myString.length();i++){
if(myString.charAt(i) == '+'||myString.charAt(i) == '-'){ //将加减添加到后缀表达式
if(list.isEmpty()){
list.add(myString.charAt(i));
}else {
while (!list.isEmpty()) {
if(!(suffixExpression.charAt(suffixExpression.length()-1) == ' '))
suffixExpression += " ";
suffixExpression += list.get(list.size() - 1);
suffixExpression += " ";
list.remove(list.size() - 1);
}
list.add(myString.charAt(i));
}
}else if(myString.charAt(i) == '*'||myString.charAt(i) == '/'){ //将乘除添加到后缀表达式
if(list.isEmpty()){
list.add(myString.charAt(i));
}else if(list.get(list.size() - 1) == '*'
||list.get(list.size() - 1) == '/') {
do {
if(!(suffixExpression.charAt(suffixExpression.length()-1) == ' '))
suffixExpression += " ";
suffixExpression += list.get(list.size() - 1);
suffixExpression += " ";
list.remove(list.size() - 1);
if(list.isEmpty())
break;
}while (list.get(list.size() - 1) == '