我有(x1 & x2) || (x3 || !x4)
之类的陈述。
我会把这个陈述变成一棵树。
问题是如何生成true
,false
值到x
变量并获取此语句的所有输出?
我们有*T
作为树根和所有树函数。也就是将树定义为链表树。
答案 0 :(得分:1)
你是不是喜欢这样的?根据您实际创建和操作树的方式,您可能希望查看内存管理;这个例子很简陋。您还可能希望为输出添加调试标志。
#include <string>
#include <vector>
#include <iostream>
class Variable
{
public:
Variable(const std::string& name = "Un-named", bool value = false)
: name_(name)
{}
void setValue(bool val)
{
value_ = val;
}
bool getValue() const
{
return value_;
}
const std::string& getName() const { return name_;}
void setName(const std::string& name) { name_ = name;}
private:
std::string name_;
bool value_;
};
class NodeAbc
{
public:
virtual bool getValue() const = 0;
virtual std::ostream& operator<<(std::ostream& os) const = 0;
virtual ~NodeAbc() = 0;
};
NodeAbc::~NodeAbc() { }
std::ostream& operator<<(std::ostream& os, const NodeAbc& rhs)
{
return rhs << os;
}
class NodeAtom : public NodeAbc
{
public:
NodeAtom(const Variable* atom)
: v_(atom)
{}
// Default copy OK for Atom.
virtual bool getValue() const { return v_->getValue();}
virtual std::ostream& operator<<(std::ostream& os) const
{
return os << v_->getName();
}
private:
// Not owned, so no free in destructor;
const Variable* v_;
};
class UnaryOpAbc
{
public:
// No virtual destructor - stateless type
virtual bool eval(bool lhs) const = 0;
virtual std::string getName() const = 0;
};
class Not : public UnaryOpAbc
{
public:
virtual bool eval(bool lhs) const { return !lhs;}
virtual std::string getName() const { return "!";}
};
class BinaryOpAbc
{
public:
// No virtual destructor - stateless type
virtual bool eval(bool lhs, bool rhs) const = 0;
virtual std::string getName() const = 0;
};
class And : public BinaryOpAbc
{
public:
virtual bool eval(bool lhs, bool rhs) const{ return lhs && rhs;}
virtual std::string getName() const { return "&&";}
};
class Or : public BinaryOpAbc
{
public:
virtual bool eval(bool lhs, bool rhs) const{ return lhs || rhs;}
virtual std::string getName()const { return "||";}
};
struct Operators
{
static And and;
static Or or;
static Not not;
};
And Operators::and;
Or Operators::or;
Not Operators::not;
class NodeBinary : public NodeAbc
{
public:
NodeBinary(NodeAbc* lhs, NodeAbc* rhs, const BinaryOpAbc& op )
: lhs_(lhs),
rhs_(rhs),
op_(op)
{}
virtual ~NodeBinary()
{
delete lhs_;
delete rhs_;
}
virtual bool getValue() const { return op_.eval( lhs_->getValue(), rhs_->getValue());}
virtual std::ostream& operator<<(std::ostream& os) const
{
return os << "(" << *lhs_ << " " << op_.getName() << " " << *rhs_<< " )";
}
private:
// No copy;
NodeBinary(const NodeBinary& other);
NodeAbc* lhs_;
NodeAbc* rhs_;
const BinaryOpAbc& op_;
};
class NodeUnary : public NodeAbc
{
public:
NodeUnary(NodeAbc* lhs, const UnaryOpAbc& op )
: lhs_(lhs),
op_(op)
{}
virtual ~NodeUnary()
{
delete lhs_;
}
virtual bool getValue() const { return op_.eval( lhs_->getValue());}
virtual std::ostream& operator<<(std::ostream& os) const
{
return os << op_.getName() << *lhs_;
}
private:
// No copy.
NodeUnary(const NodeUnary& other);
NodeAbc* lhs_;
const UnaryOpAbc& op_;
};
int main(int argc, _TCHAR* argv[])
{
std::vector<Variable> variables(4);
Variable* x1 = &(variables[0] = Variable("x1", true));
Variable* x2 = &(variables[1] = Variable("x2", true));
Variable* x3 = &(variables[2] = Variable("x3", true));
Variable* x4 = &(variables[3] = Variable("x4", true));
NodeAbc* x1AndX2 = new NodeBinary( new NodeAtom(x1), new NodeAtom(x2), Operators::and);
NodeAbc* notX4 = new NodeUnary( new NodeAtom(x4), Operators::not);
NodeAbc* x3OrNotX4 = new NodeBinary( new NodeAtom(x3),notX4 , Operators::or);
NodeAbc* root = new NodeBinary(x1AndX2, x3OrNotX4, Operators::or);
std::cout << * root << "\t" << root->getValue() << std::endl;
x2->setValue(false);
x3->setValue(false);
std::cout << * root << "\t" << root->getValue() << std::endl;
delete root;
return 0;
}
答案 1 :(得分:0)
您的树应该存储键值对,这意味着不仅存储x1,还存储它的值(True
或False
)。以这种方式创建树后,您可以遍历树以查找结果。
答案 2 :(得分:0)
除了你的树,你需要一个符号表 符号表的作用是将变量映射到值:
typedef std::map<std::string, ValueType> SymbolTable;
SymbolTable symbolTable;
然后,如果我们假设您的表达式树已经评估了接口。您只需将符号表作为参数传递给评估。
class Node
{
virtual ValueType evaluated(SymbolTable const& symbols) = 0;
};
class Variable: public Node
{
std::string name;
Variable( std::string const& n) : name(n) {};
virtual ValueType evaluated(SymbolTable const& symbols)
{
return symbols[name]; // looks up the value of the variable in the symbol table.
}
};
class NotNode: public Node
{
std::auto_ptr<Node> child;
NotNode(std::auto_ptr<Node> x): child(c) {}
virtual ValueType evaluated(SymbolTable const& symbols)
{
return child->evaluated(symbols).not(); // Assume Value type knows how to not itself.
}
}
// etc
当您在根音符上调用evaluate时,您只需传递当前符号表进行评估,然后您应该返回结果。