C++ 德摩根';使用C/C和#x2B+;

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(

表达式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() {};
        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定律算法)实际上是答案的关键。我明白了。非常感谢。