如何使用树c++计算布尔语句

how to evaluate a boolean statement using tree c++

本文关键字:布尔 语句 计算 c++ 何使用      更新时间:2023-10-16

我有一个类似(x1 & x2) || (x3 || !x4)的语句。我将把这句话变成一棵树。问题是如何生成truefalse值并将其分配给x变量,并获得该语句的所有输出?

我们把*T作为树根,把所有的树函数都定义为链表树。

你在追求这样的东西吗?根据实际创建和操作树的方式,您可能希望查看内存管理;它在示例中是初级的。您可能还想为输出添加一个调试标志。

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

除了树之外,还需要一个符号表
符号表的工作是将变量映射到值:

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时,你只需要传递当前的符号表来进行评估,你应该会得到结果。

树应该存储键值对,这意味着不仅存储x1,还存储它的值(TrueFalse)。以这种方式创建树后,您可以遍历树以找到结果。