检查布尔数学公式是否在正确的表格中

时间:2017-02-27 16:14:52

标签: python recursion boolean logic phrase

我正在创建一个程序,它将一个布尔表达式作为一个字符串,并将中缀公式转换为postfix,同时确保公式是有效的形式。我正在努力做的是弄清楚一种检查输入公式是否有效的方法。允许 NO IMPORTING (使用内置的python函数/方法),允许循环和递归。如果公式无效,则返回None。

公式可以包含:

variables in 'abcdefghijklmnopqrstuvwxyz'
operators in '-+*'

其中 - 是NOT,+是OR,*是AND

以下是一些有效的公式(作为Python字符串)。

"x" 
"-y" 
"(x*y)" 
"((-x+y)*(-y+x))" 

以下是一些不是公式的字符串。

"X" variable not lower case letter 
"x*y" missing parentheses 
"-(x)" extraneous parentheses 
"(x+(y)*z)" mismatched parentheses

一些转换示例是:

(x+y) -> xy+
(x*y) -> xy*
-(x+y) -> xy+-
-x -> x-
((x*y)+(z*x)) -> xy*zx*+

不需要完整的工作程序,检查公式是否有效的算法很好。

我目前的实现将公式从中缀转换为后缀:

def infix_to_postfix(infix_expression):
    precedence  = {}
    precedence["*"] = 2
    precedence["+"] = 2
    precedence["-"] = 2
    precedence["("] = 1
    storage_stack = Stack()
    postfix_list = []
    tokenList = list(infix_expression)
    for token in tokenList:
        if(token not in "-+*()"):
            postfix_list.append(token)
        elif(token == '-'):
            storage_stack.push(token)
        elif(token == '('):
            storage_stack.push(token)
        elif(token == ')'):
            topToken = storage_stack.pop()
            while(topToken != '('):
                postfix_list.append(topToken)
                topToken = storage_stack.pop()
        else:
            while(not storage_stack.is_empty() and precedence[storage_stack.peek()] >= precedence[token]):
                postfix_list.append(storage_stack.pop())
            storage_stack.push(token)
    while(not storage_stack.is_empty()):
        postfix_list.append(storage_stack.pop())
    result = "".join(postfix_list)
    return result

我需要找到一种方法来检查公式是否有效更改运算符和变量的位置。

编辑:

我想出了一个算法的一部分来检查公式是否有效:

((a+b)*(c+d))
F1 = (a+b)
F2 = (c+d)
((a+b)*(c+d)) = (F1 * F2)
If F1 and F2 are valid, then the whole thing is valid.

括号内的公式在以下情况下有效: 有(和),两个子公式之间有+或*,两个子公式都有效。

我有这个检查的想法,但我不知道如何实现它。最有可能是递归。

1 个答案:

答案 0 :(得分:0)

这是一个古老的问题,但是对于有相同问题的人来说,这是一个潜在的解决方案。

import re


def formula(string):
    if not string: return 0
    string = re.sub("[^0-9+*/%-=]", "", string)

try:
    string, result = string.split("=")
    return eval(string) == int(result)
except:
    return 0