实现一个函数 terms(s:str),输入s为一合式公式,返回s的主析取范式中包含合取式的数量。其中,s中的联结词仅可能包含一,^,V,分别用 not,and,or 表示,s中的变元包含且仅包含P,Q,R。
时间: 2023-05-30 17:01:16 浏览: 115
计算主合取范式,主析取范式
思路:
首先将s转化为后缀表达式,然后通过后缀表达式构建语法树。接着对语法树进行遍历,将其转化为主析取范式,并统计其中包含合取式的数量。
具体步骤如下:
1. 将s转化为后缀表达式。
2. 通过后缀表达式构建语法树。
3. 对语法树进行后序遍历,将其转化为主析取范式。
4. 统计主析取范式中包含合取式的数量。
代码实现如下:
```python
class ExpressionTree:
def __init__(self, value):
self.value = value
self.left = None
self.right = None
def terms(s):
postfix = to_postfix(s)
root = build_expression_tree(postfix)
cnf = to_cnf(root)
return count_conjunction(cnf)
def to_postfix(s):
op_stack = []
output = []
for c in s:
if c in 'PQR':
output.append(c)
elif c == '(':
op_stack.append(c)
elif c == ')':
while op_stack and op_stack[-1] != '(':
output.append(op_stack.pop())
op_stack.pop()
else:
while op_stack and op_stack[-1] != '(' and precedence(c) <= precedence(op_stack[-1]):
output.append(op_stack.pop())
op_stack.append(c)
while op_stack:
output.append(op_stack.pop())
return output
def build_expression_tree(postfix):
stack = []
for c in postfix:
if c in 'PQR':
node = ExpressionTree(c)
stack.append(node)
else:
right = stack.pop()
left = stack.pop()
node = ExpressionTree(c)
node.left = left
node.right = right
stack.append(node)
return stack[0]
def to_cnf(root):
if not root.left and not root.right:
return root.value
left = to_cnf(root.left)
right = to_cnf(root.right)
op = root.value
if op == '^':
return '(%s)' % ('&'.join(['(%s)' % (x + '|' + y) for x in left.split('&') for y in right.split('&')]))
elif op == 'V':
return '(%s)' % ('|'.join(['(%s)' % (x + '&' + y) for x in left.split('|') for y in right.split('|')]))
elif op == 'not':
if len(left) == 1:
return '~' + left
else:
return left[1:]
else:
return ''
def count_conjunction(s):
count = 0
for sub in s.split('|'):
if '&' in sub:
count += 1
return count
def precedence(c):
if c == '(':
return 0
elif c == 'V':
return 1
elif c == '^':
return 2
else:
return 3
```
阅读全文