表达式树程序

在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;
}

posted @ 2011-02-28 14:44  macula7  阅读(306)  评论(0编辑  收藏  举报