题目
https://www.lintcode.com/problem/271
将一个前缀表达式转换成后缀表达式。
输入的前缀表达式的字符串长度为 l,满足
1≤l≤10 ^4
表达式中只包括四种符号 ‘+’,‘-’,‘*’,‘/’。
每个符号和变量之间用一个空格隔开。
样例中的中缀表达式是 "a - (b + c)"。
样例
输入:
str = "- a + b c"
输出:
"a b c + -"
思路
本题考查的是前缀表达式后缀表达式和表达式树的关系。
表达式树所有的叶节点都是变量,非叶节点就是符号,连接两个子节点,
它将获取子节点并且进行运算。
表达式树的中序遍历就是我们常见的中缀表达式。
前缀表达式就是表达式树的前序遍历,
后缀表达式就是表达式树的后序遍历。
本题需要将前缀表达式转换成表达式树的形式,
并且进行后序遍历就可以得到后缀表达式。
代码思路
前缀表达式转换成表达式树:
维护一个树节点的栈,倒序遍历前缀表达式:
如果是变量,直接将这个变量的节点压入栈中。
如果是符号,取出栈顶的两个节点,分别作为左右子节点,并将这个节点压入栈中。
最后栈中剩下的节点就是表达式树的根节点。
答案
public class Solution {
/**
* @param str: the prefix notation.
* @return: return the postfix notation.
*/
public String prefixNotationToPostfixNotation(String str) {
/*
本题考查的是前缀表达式后缀表达式和表达式树的关系。
表达式树所有的叶节点都是变量,非叶节点就是符号,连接两个子节点,
它将获取子节点并且进行运算。
表达式树的中序遍历就是我们常见的中缀表达式。
前缀表达式就是表达式树的前序遍历,
后缀表达式就是表达式树的后序遍历。
本题需要将前缀表达式转换成表达式树的形式,
并且进行后序遍历就可以得到后缀表达式。
代码思路
前缀表达式转换成表达式树:
维护一个树节点的栈,倒序遍历前缀表达式:
如果是变量,直接将这个变量的节点压入栈中。
如果是符号,取出栈顶的两个节点,分别作为左右子节点,并将这个节点压入栈中。
最后栈中剩下的节点就是表达式树的根节点。
*/
String[] tokens = str.split(" ");
//建立表达式树
Node expressTree = buildExpTree(tokens);
//获得表达式树的后序遍历
List<String> postOrder = new ArrayList<>();
postTravel(expressTree,postOrder);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < postOrder.size(); i++) {
if(i>0) sb.append(" ");
sb.append(postOrder.get(i));
}
return sb.toString();
}
public static Node buildExpTree(String[] strs){
Stack<Node> stack = new Stack<>();
//倒序遍历前缀表达式树构造表达式树
int n= strs.length;
for (int i = n-1; i >=0 ; i--) {
Node node = new Node(strs[i]);
if(isOperation(strs[i])){
//如果是操作符,取除栈中2个元素,作为当前节点的子节点
node.left = stack.pop();
node.right = stack.pop();
//并将这个阶段压入栈中
stack.add(node);
}else{
//如果是变量,直接压入栈中
stack.add(node);
}
}
return stack.peek();
}
//判断是否是操作符
public static boolean isOperation(String s){
return "+-*/".indexOf(s) !=-1;
}
public static void postTravel(Node root,List<String> postOrder){
if(root ==null)
return;
postTravel(root.left,postOrder);
postTravel(root.right,postOrder);
postOrder.add(root.data);
}
static class Node{
String data;
Node left,right;
public Node(String d){
data =d;
left=right =null;
}
}
}