• 表达式树程序


    在c++沉思录举了一个表达式树的例子,将例如(-5)*(3+4)的式子表示成树的形式。可以通过如下形式:

    Expr t = Expr("*", Expr("-", 5), Expr("+", 3, 4));
    cout<<t<<" = "<<t.eval()<<endl;
    

    创建树并将树打印出来。

    这个程序主要用于理解动态绑定和句柄,程序实现代码如下:

    #include <iostream>
    #include
    <string>
    /*
    所有节点类型的父类
    */
    class Expr_node{
    // friend ostream& operator<<(ostream&, const Expr&);
    friend class Expr;
    int use;
    protected:
    Expr_node():use(
    1){}
    virtual int eval()const = 0;
    public:
    virtual void print(ostream &)const = 0;//书中这个方法是protected修饰的,但是放在那里会报错
    virtual ~Expr_node(){}
    };

    /**
    句柄类
    */
    class Expr{
    //重载操作符
    friend ostream& operator<<(ostream&, const Expr&);
    Expr_node
    * p;
    public:
    Expr(
    int);
    Expr(
    const string &, Expr);
    Expr(
    const string &, Expr, Expr);
    Expr(
    const Expr&t){ p = t.p; ++p->use; };
    Expr
    & operator=(const Expr &);
    ~Expr(){if(--p->use==0)delete p;}
    int eval()const {return p->eval();}
    //ostream& operator<<(ostream&, const Expr&)const;
    };
    class Int_node: public Expr_node{
    friend
    class Expr;
    int n;
    Int_node(
    int k):n(k){}
    void print(ostream &o)const{o<<n;}
    int eval()const{return n;}
    };

    class Unary_node:public Expr_node{
    friend
    class Expr;
    string op;
    Expr opnd;
    Unary_node(
    const string a, Expr b):op(a),opnd(b){}
    void print(ostream& o)const {o << "(" << op << opnd << ")";}
    int eval()const;
    };
    int
    Unary_node::eval()
    const
    {
    if(op == "-")
    return -opnd.eval();
    throw "error,bad op " + op + "in unarnode";
    }

    class Binary_node: public Expr_node{
    friend
    class Expr;
    string op;
    Expr left;
    Expr right;
    Binary_node(
    const string &a, Expr b, Expr c):
    op(a), left(b), right(c){}
    int eval()const;
    void print(ostream& o)const
    {
    o
    << "(" << left << op << right<< ")";
    }

    };
    int
    Binary_node::eval()
    const
    {
    int op1 = left.eval();
    int op2 = right.eval();
    if(op == "-") return op1 - op2;
    if(op == "+") return op1 + op2;
    if(op == "*") return op1 * op2;
    if(op =="/" && op2 != 0) return op1 / op2;
    throw "error, bad op " + op + "in binarynode" ;
    }

    Expr::Expr(
    int n)
    {
    p
    = new Int_node(n);
    }
    Expr::Expr(
    const string &op, Expr t)
    {
    p
    = new Unary_node(op, t);
    }
    Expr::Expr(
    const string &op, Expr left, Expr right)
    {
    p
    = new Binary_node(op, left, right);
    }
    Expr
    &
    Expr::
    operator=(const Expr& rhs)
    {
    rhs.p
    ->use++;
    if(--p->use == 0)
    delete p;
    p
    = rhs.p;
    return *this;
    }
    ostream
    &
    operator<<(ostream& o, const Expr& t)
    {
    t.p
    ->print(o);
    return o;
    }
    int main()
    {
    Expr t
    = Expr("*", Expr("-", 5), Expr("+", 3, 4));
    cout
    <<t<<" = "<<t.eval()<<endl;
    }

  • 相关阅读:
    深入剖析ASP.NET的编译原理之二:预编译(Precompilation)
    六个建议防止SQL注入式攻击
    微软IIS的ISAPI筛选器权限法则
    IIS属性没有ASP.NET选项
    让我们的服务器更安全Win03 防木马权限设置,IIS服务器安全配置
    IIS自动停止,iis自动关闭。应用程序池假死、自动重启以及iis权限等解决办法
    深入剖析ASP.NET的编译原理之一:动态编译(Dynamical Compilation)
    c#操作xml
    C# 容易出现insert into语句的语法错误的原因
    兼容ie/火狐的全能日历代码含农历
  • 原文地址:https://www.cnblogs.com/macula7/p/1966962.html
Copyright © 2020-2023  润新知