如何将命题逻辑树转化为合取范式树
how to convert a propositional logical tree into conjunction normal form (CNF) tree
我有一个string
s="(=> P (OR (AND A (NOT B)) (AND B (NOT A))))";
并将其转换为该字符串的CNF输出,如
(OR (NOT p) (OR A B))(OR (NOT P) (OR (NOT B) (NOT A)))
我需要做一个结构体TreeNode来保持值吗?
struct TreeNode {
string val; // The data in this node.
TreeNode *left; // Pointer to the left subtree.
TreeNode *right; // Pointer to the right subtree.
//TreeNode *farther;//should I use farther or not in convert to CNF?
};
如何转化为合取范式的CNF ?请给出一些算法细节。从我的角度来看,也许使用递归函数更好地解决这个问题,但我仍然想不出如何使用递归。或者你有其他的建议来解决这个问题?
假设您将函数命名为CNF
,取树并以CNF返回树。
-
首先用
AND(p=>q,q=>p)
代替等价的p<=>q
,然后用OR(q,NOT(p))
代替含义的p=>q
。 -
转换为否定范式:将所有
NOT
操作移到树下,以便NOT
操作仅绑定原子(A
,B
)。 -
然后,
CNF(AND(x,y))
的结果很简单:AND(CNF(x),CNF(y))
,因为它是CNF-like将AND
放在树的高位 -
CNF(OR(AND(x,y),z))
的结果有点复杂。这里我们将使用析取/合取的分布规则,即OR(AND(x,y),z)
等价于AND(OR(x,z),OR(y,z))
。实际上,CNF(OR(AND(x,y),z))
将是AND(OR(CNF(x),CNF(z)),OR(CNF(y),CNF(z))
。
简单递归下降解析器解决方案:
TreeNode* ParseExpression(const char*& p)
:如果p指向的字符串不是以'('开头的,则返回ParseAtom(p),否则将p移过'(',调用ParseOperation(p),然后将p移过')'并返回由ParseOperation返回的值。
TreeNode* ParseAtom(const char*& p)
:跳过原子(连续的非空格序列)。返回一个以原子为值的TreeNode,左右为NULL。
TreeNode* ParseOperation(const char*& p)
: p所指向的字符串应该以操作符开始。将p移过运算符,然后确定运算符使用了多少个操作数。如果有,调用ParseExpression(p)一次;如果有两个,调用ParseExpression(p)两次。然后返回一个TreeNode,操作符作为值,一个或两个ParseExpression调用的结果作为左和右(对于只有一个操作数的操作符,右应该为NULL)。
设置指向原字符串的指针;在指针上调用ParseExpression;返回值是您的树,指针将指向字符串中的第一个表达式。
这解决了你的一个问题:如何将字符串转换为树。Adrian Panasiuk解决了另一个问题,如何将树转换为标准形式。由于您将进行额外的树转换,因此节点中的"值"应该称为"op"或类似的名称,以表示"操作符"(这是c++中的保留字),并且它应该是enum,而不是字符串。
- 提升精神:解析布尔表达式并简化为规范范式
- C++选择排序算法中的逻辑错误
- 多个If语句与使用逻辑运算符计算条件的单个语句的比较
- 关于简单C++函数(is_palindrome)的逻辑的问题
- 如何打开并写入一个名称取自C++中字符串的文件
- 逻辑运算符上出现错误代码 a')'
- 无法在问题解决方案中执行输出逻辑
- 当我尝试在 Main 中调用插入函数时,它不是取数字?
- 我的逻辑反转字符串中的元音有什么问题?
- scanf() 只取数字作为输入,避免使用其他字符
- 如果语句逻辑不正确
- 我可以使用任何好的逻辑来阻止计算机将 O 放在井字游戏中的现有 X 上
- CIN是逻辑1还是0?
- 尝试创建表会给出 SQL 逻辑错误
- 我可以通过取每个数字的模并取和来计算大数的模数吗?
- 寻找闰年的逻辑是如何运作的?
- C++ 合相范式正则表达式
- 如何使用'bit-blast'方法以命题逻辑形式打印给定的公式?
- 逻辑帮助:比较值并取最小距离,同时将其从"available to compare"列表中删除
- 如何将命题逻辑树转化为合取范式树