逆波兰表达式 中缀表达式 后缀表达式
前言
逆波兰表达式又叫做后缀表达式。在通常的表达式中,二元运算符总是置于与之相关的两个运算对象之间,这种表示法也称为中缀表示。波兰逻辑学家J.Lukasiewicz于1929年提出了另一种表示表达式的方法,按此方法,每一运算符都置于其运算对象之后,故称为后缀表示. [ 百度百科 ]
开始
1 .我们这里要实现的是 将中缀表达式转换成后缀表达式,然后再计算最终结果,参考博客。具体转化算法如下:
中缀表达式a+b*c+(d*e+f)*g,其转换成后缀表达式则为abc*+de*f+g*+。
转换过程需要用到栈,具体过程如下:
1)如果遇到操作数,我们就直接将其输出。
2)如果遇到操作符,则我们将其放入到栈中,遇到左括号时我们也将其放入栈中。
3)如果遇到一个右括号,则将栈元素弹出,将弹出的操作符输出直到遇到左括号为止。注意,左括号只弹出并不输出。
4)如果遇到任何其他的操作符,如(“+”, “*”,“(”)等,从栈中弹出元素直到遇到发现更低优先级的元素(或者栈为空)为止。弹出完这些元素后,才将遇到的操作符压入到栈中。有一点需要注意,只有在遇到" ) "的情况下我们才弹出" ( ",其他情况我们都不会弹出" ( "。
5)如果我们读到了输入的末尾,则将栈中所有元素依次弹出。
2.代码实现如下:
/**
* @param sign 运算符
* @return int 运算符优先级
*/
public static int getRank(Character sign) {
switch (sign) {
case '+':
case '-':
return 1;
case '*':
case '/':
return 2;
}
return -1;
}
public static void main(String[] args) throws Exception {
String expression = "a+b*c+(d*e+f)*g";
Stack<Character> stackTemp = new Stack<Character>();
Queue<Character> queueOut = new LinkedList<Character>();
for (Character word : expression.toCharArray()) {
if (word >= 'a' && word <= 'z') {
queueOut.offer(word);
} else if (word == '(') {
stackTemp.push(word);
} else if (word == ')') {
char top = stackTemp.peek();
while (!stackTemp.empty()) {
if (top == '(') {
stackTemp.pop();
break;
}
queueOut.offer(top);
stackTemp.pop();
top = stackTemp.peek();
}
} else {
if (stackTemp.empty() || getRank(word) > getRank(stackTemp.peek())) {
stackTemp.push(word);
} else {
while (!stackTemp.empty() && getRank(word) <= getRank(stackTemp.peek())) {
queueOut.offer(stackTemp.peek());
stackTemp.pop();
}
stackTemp.push(word);
}
}
}
while (!stackTemp.empty()) {
queueOut.offer(stackTemp.peek());
stackTemp.pop();
}
/*输出结果*/
while (!queueOut.isEmpty()) {
System.out.print(queueOut.poll());
}
}
3.输出结果即后缀表达式(逆波兰表达式):abc*+de*f+g*+
4.计算逆波兰表达式,得到最终运算结果,待续.