LintCode上的一道题,表达树构造,大意是给出一个算术表达式,要我们构造它的表达树。
可以通过压栈和出栈来处理表达式中的括号,但乘除法优先级比加减法高且不需要括号标识,处理起来比较麻烦。
琢磨了半天才搞出来,写得比较别扭,以后有时间再改进。
/**
* Definition of ExpressionTreeNode:
* class ExpressionTreeNode {
* public:
* string symbol;
* ExpressionTreeNode *left, *right;
* ExpressionTreeNode(string symbol) {
* this->symbol = symbol;
* this->left = this->right = NULL;
* }
* }
*/
class Solution {
public:
/**
* @param expression: A string array
* @return: The root of expression tree
*/
vector<ExpressionTreeNode*> stack;
ExpressionTreeNode* build(vector<string> &expression) {
// write your code here
ExpressionTreeNode* root = new ExpressionTreeNode("");
stack.push_back(root);
for(int i = 0; i < expression.size(); ++i){
ExpressionTreeNode* node = getNode(0);
string& s = expression[i];
if(s == "+" || s == "-"){
if(node->symbol == "*" || node->symbol == "/"){ //前面是乘除法的要出栈
unbrackSub();
}
node = getNode(0);
if(node->symbol == ""){
node->symbol = s;
continue;
}
lfunc(s);
}else if(s == "*" || s == "/"){
if(node->symbol == "*" || node->symbol == "/"){
lfunc(s);
}else {
rfunc(s);
}
}else if(s == "(" || s == "[" || s == "{"){
brack();
}else if(s == ")" || s == "]" || s == "}"){
unbrack();
}else{
if(node->symbol == ""){
node->symbol = s;
}else if(node->left == NULL){
node->left = new ExpressionTreeNode(s);
}else if(node->right == NULL){
node->right = new ExpressionTreeNode(s);
}
}
}
unbrack(); //再出栈一次清除符号为""的情况
if(root->symbol == ""){ //考虑到只有括号的情况
return NULL;
}else{
return root;
}
}
void lfunc(string& s){ //平等优先级操作符
ExpressionTreeNode* node = getNode(0);
ExpressionTreeNode* lnode = new ExpressionTreeNode(node->symbol);
lnode->left = node->left;
lnode->right = node->right;
node->left = lnode;
node->symbol = s;
node->right = NULL;
}
void rfunc(string& s){ //高优先级操作符
ExpressionTreeNode* node = getNode(0);
ExpressionTreeNode* rnode = new ExpressionTreeNode(s);
if(node->right == NULL){
if(node->left == NULL){ //叶子节点
rnode->left = new ExpressionTreeNode(node->symbol);
node->symbol = "";
}else{ //缺右子树的加减法节点
rnode->left = node->left;
node->left = NULL;
}
}else{ //完整的加减法节点
rnode->left = node->right;
node->right = NULL;
}
stack.push_back(rnode); //乘除法都压栈
}
void brack(){ //括号操作
stack.push_back(new ExpressionTreeNode(""));
}
void unbrack(){ //反括号操作
ExpressionTreeNode* node = getNode(0);
if(node->symbol == "*" || node->symbol == "/"){ //如果有乘除法未出栈先将他们出栈
unbrackSub();
}
unbrackSub(); //再进行一次针对括号的出栈操作
}
void unbrackSub(){//出栈操作
ExpressionTreeNode* pnode = getNode(-1);
ExpressionTreeNode* node = getNode(0);
if(node->symbol == ""){
ExpressionTreeNode* l = node->left;
if(l != NULL){
node->symbol = l->symbol;
node->left = l->left;
node->right = l->right;
}
}
if(pnode != NULL){
if(pnode->left == NULL){
pnode->left = node;
}else{
pnode->right = node;
}
stack.pop_back();
}
}
ExpressionTreeNode* getNode(int index){
int p = stack.size() + index - 1;
if(p >= 0){
return stack[p];
}else{
return NULL;
}
}
};