如何使用树c++计算布尔语句
how to evaluate a boolean statement using tree c++
我有一个类似(x1 & x2) || (x3 || !x4)
的语句。我将把这句话变成一棵树。问题是如何生成true
、false
值并将其分配给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,还存储它的值(True
或False
)。以这种方式创建树后,您可以遍历树以找到结果。
相关文章:
- 如何编写一个使用n倍三元条件语句的C++布尔函数
- 为什么布尔开关语句有编译器警告?
- 递归函数、布尔语句和输入C++
- 带有关闭/打开布尔值的开关语句
- 在 if 语句中返回布尔值的 lambda 表达式
- 在单个if语句中测试多个布尔值
- 布尔变量 if 语句 C++ 上的分段错误
- 在一个语句中对原子布尔变量进行多次赋值
- 关闭文件流时出错,其存在取决于与 C++ 中的 .close() 语句相同的布尔值
- 布尔逻辑,If 语句约简
- C++ 嵌套'if'语句中的所有代码都会运行,即使这会更改外部语句的布尔值?
- 可能由if语句引起的C++布尔逻辑错误
- 布尔语句形式 c++
- 如何启动具有许多布尔参数的函数模板,而不使用 2^n if 语句
- 布尔循环和开关语句
- C++Bare布尔表达式(不包含if、while或其他语句)
- 避免使用静态布尔值上的if语句进行逻辑决策
- 在C++中添加布尔表达式切换语句
- 如何使用树c++计算布尔语句
- 这段c++代码是如何处理不寻常的单个布尔语句的?