C++ 德摩根';使用C/C和#x2B+;
表达式1:(A和B或(非C))C++ 德摩根';使用C/C和#x2B+;,c++,c,demorgans-law,C++,C,Demorgans Law,表达式1:(A和B或(非C)) 表达式2:非((非A)或(非B)和C) 我想将表达式2更改为表达式1。因此,表达式可以表示为一棵树,如下图所示。这意味着“not”操作只能存在于叶节点中 转换基于 我的问题是: 是否有C/C++库实现此功能?我对C/C++库了解不多。我搜索了一下,但没有找到答案 谢谢大家! 当你反复思考时,规则很简单: 非(X和Y)=>(非X)或(非Y) 非(X或Y)=>(非X)和(非Y) 所以在C++中: struct Node { virtual ~Node(
谢谢大家! 当你反复思考时,规则很简单:
=>非(X和Y)
(非X)或(非Y)
=>非(X或Y)
(非X)和(非Y)
struct Node {
virtual ~Node() {};
virtual Node *copy() = 0;
virtual Node *negation() = 0;
private:
// Taboo
Node(const Node&);
Node& operator=(const Node&);
};
struct AndNode : Node {
Node *left, *right;
AndNode(Node *left, Node *right) : left(left), right(right) {}
~AndNode() { delete left; delete right; }
Node *copy() { return new AndNode(left->copy(), right->copy()); }
Node *negation();
};
struct OrNode : Node {
Node *left, *right;
OrNode(Node *left, Node *right) : left(left), right(right) {}
~OrNode() { delete left; delete right; }
Node *copy() { return new OrNode(left->copy(), right->copy()); }
Node *negation();
};
struct NotNode : Node {
Node *x;
NotNode(Node *x) : x(x) {}
~NotNode() { delete x; }
Node *copy() { return new NotNode(x->copy()); }
Node *negation();
};
struct VarNode : Node {
std::string var;
VarNode(const std::string& var) : var(var) {}
Node *copy() { return new VarNode(var); }
};
否定
和和或
操作的代码只应用了德摩根定律,从而将否定“推”到树下
Node *AndNode::negation() {
return new OrNode(left->negation(), right->negation());
}
Node *OrNode::negation() {
return new AndNode(left->negation(), right->negation());
}
否定的否定代替了省略的简化
Node *NotNode::negation() {
return x->copy();
}
只有叶节点实际包装在否定操作中
Node *VarNode::negation() {
return new NotNode(this->copy());
}
正如你所看到的,摩根定律只是两条线,其他的都是如何在C++中表示表达式树。只有一个库来实现De Morgan的转换是没有意义的,因为一旦有了表示,它绝对是微不足道的
一个能够使用不同树表示的包装器实现将是99%的样板文件和接口代码,以实现一个两行程序(完全是胡说八道)
只需使用您拥有的任何树表示直接实现即可。您的树是AST,也称为EBNF/BNF树或语法树;真正的问题是:你在解析什么样的语言?在我看来,你可以从根开始,将
NOT(a{AND | OR}b)
转换为(NOT a{OR{AND}(NOT b)
(如果需要的话),然后以类似的方式处理每个孩子——确保消除双重否定。你真的不需要一个图书馆来做这件事。你没有告诉我们足够的信息来保证提供一个有用的答案。如果我们假设您将逻辑表达式放入一个boost::graph
或lemon
(可以搜索它们),那么您当然可以在树中向下搜索,查看一些节点是否表示“表达式2”情况,并将其简化为“表达式1”。有许多可用的图形库,但我认为您必须编写自己的结构来表示逻辑操作和/或值,以及您自己的De Morgan替换代码。在没有填充图形的情况下使用可疑,并使用结果。非常感谢。由于不存在一些库,我将自己编写代码。虽然这说明了原理很好,但是请不要在C++中编写这样的代码。使用有价值的对象和/或智能指针。@KonradRudolph:不可否认,我对裸体指针有着疯狂的热情,并且有点过度使用它们的倾向。然而,证明问题是树表示(而不是De Morgan定律算法)实际上是答案的关键。我明白了。非常感谢。