1628 设计带解析函数的表达式树

题目描述:
给定一个算术表达式的后缀表示法的标记(token) postfix ,构造并返回该表达式对应的二叉表达式树。
后缀表示法是一种将操作数写在运算符之前的表示法。例如,表达式 4*(5-(2+7)) 的后缀表示法表示为数组 postfix = [“4”,“5”,“7”,“2”,"+","-","*"] 。
抽象类 Node 需要用于实现二叉表达式树。我们将通过 evaluate 函数来测试返回的树是否能够解析树中的值。你不可以移除 Node 类,但你可以按需修改此类,也可以定义其他类来实现它。

二叉表达式树是一种表达算术表达式的二叉树。二叉表达式树中的每一个节点都有零个或两个子节点。 叶节点(有 0 个子节点的节点)表示操作数,非叶节点(有 2 个子节点的节点)表示运算符: ‘+’ (加)、 ‘-’ (减)、 ‘*’ (乘)和 ‘/’ (除)。
我们保证任何子树对应值的绝对值不超过 109 ,且所有操作都是有效的(即没有除以零的操作)
进阶: 你可以将表达式树设计得更模块化吗?例如,你的设计能够不修改现有的 evaluate 的实现就能支持更多的操作符吗?

示例 1:
在这里插入图片描述
输入: s = [“3”,“4”,"+",“2”,"*",“7”,"/"]
输出: 2
解释: 此表达式可解析为上述二叉树,其对应表达式为 ((3+4)*2)/7) = 14/7 = 2.

示例 2:
在这里插入图片描述
输入: s = [“4”,“5”,“7”,“2”,"+","-",""]
输出: -16
解释: 此表达式可解析为上述二叉树,其对应表达式为 4
(5-(2+7)) = 4*(-4) = -16.

示例 3:
输入: s = [“4”,“2”,"+",“3”,“5”,“1”,"-","*","+"]
输出: 18

示例 4:
输入: s = [“100”,“200”,"+",“2”,"/",“5”,"*",“7”,"+"]
输出: 757

提示:
1 <= s.length < 100
s.length 是奇数。
s 包含数字和字符 ‘+’ 、 ‘-’ 、 ‘*’ 以及 ‘/’ 。
如果 s[i] 是数,则对应的整数不超过 105 。
s 保证是一个有效的表达式。
结果值和所有过程值的绝对值均不超过 109 。
保证表达式不包含除以零的操作。

方法1:
主要思路:解题链接汇总
(1)栈+dfs;
(2)利用栈构造表达式树,使用dfs解析该表达式树;

/**
 * This is the interface for the expression tree Node.
 * You should not remove it, and you can define some classes to implement it.
 */

class Node {
    
    
public:
    virtual ~Node () {
    
    };
    virtual int evaluate() const = 0;
    int val;
    char ch;
    Node* left;
    Node* right;
protected:
    // define your fields here

};

class NewNode:public Node{
    
    
    public:
    NewNode(int v){
    
    
        val=v;
        left=NULL;
        right=NULL;
    }
    NewNode(char v){
    
    
        ch=v;
        left=NULL;
        right=NULL;
    }
    int evaluate() const{
    
    
        if(right==NULL&&left==NULL){
    
    //若是叶子结点,则直接返回该结点的值
            return val;
        }
        //否则,计算出该结点的左右子树代表的值,再将这两个值使用该结点的符号计算
        int left_val=left->evaluate();
        int right_val=right->evaluate();
        if(ch=='+'){
    
    
            return left_val+right_val;
        }
        if(ch=='-'){
    
    
            return left_val-right_val;
        }
        if(ch=='*'){
    
    
            return left_val*right_val;
        }
        return left_val/right_val;
    }
};


/**
 * This is the TreeBuilder class.
 * You can treat it as the driver code that takes the postinfix input 
 * and returns the expression tree represnting it as a Node.
 */

class TreeBuilder {
    
    
public:

    Node* buildTree(vector<string>& postfix) {
    
    
        stack<Node*> st;
        Node*root=NULL;
        for(string&str:postfix){
    
    
            if(str[0]>='0'&&str[0]<='9'){
    
    //判断当前字符串是否是数字
                int num=atoi(str.c_str());
                st.push(new NewNode(num));//是数字,则直接将该节点压入栈中
            }
            else{
    
    //是符合,则从树中取出两个结点,作为当前结点的左右结点,然后再将该节点压入栈中
                root=new NewNode(str[0]);
                root->right=st.top();
                st.pop();
                root->left=st.top();
                st.pop();        
                st.push(root);
            }
        }
        return root;
    }
};


/**
 * Your TreeBuilder object will be instantiated and called as such:
 * TreeBuilder* obj = new TreeBuilder();
 * Node* expTree = obj->buildTree(postfix);
 * int ans = expTree->evaluate();
 */

猜你喜欢

转载自blog.csdn.net/weixin_44171872/article/details/114518823