Python-包括括号在内的所有组合

Python-包括括号在内的所有组合,python,python-3.x,algorithm,itertools,Python,Python 3.x,Algorithm,Itertools,对于u未知变量(例如a、b、c、d)和符号+-*/,找到所有可能的长度n 例如(表示u=2,n=5): (a+b)/a 我当前的代码可以创建所有可能方程的列表,但没有括号 v = ["a", "b"] #Variables s = ["+", "-", "*", "-"] #Symbols n = 7 #Amount of variables and symbols a = [] #Lists

对于
u
未知变量(例如a、b、c、d)和符号
+-*/
,找到所有可能的长度
n

例如(
表示u=2,n=5
):

(a+b)/a

我当前的代码可以创建所有可能方程的列表,但没有括号

v = ["a", "b"]            #Variables
s = ["+", "-", "*", "-"]  #Symbols
n = 7                     #Amount of variables and symbols
a = []                    #Lists combined (find possible equations from)
for i in range(n):
    if i % 2 == 0:
        a.append(v)
    else:
        a.append(s)
equations = list(itertools.product(*a))
for each in equations:
    print("".join(each))
总之,我写的代码并不包含等式的所有可能性

例如,对于
n=5和2个变量
,我的代码无法找到
(a+b)*b的可能性

当n=7和4个变量时,它无法找到`(a+b)*(c+d)

我的主要问题是:我如何创建一些代码来获取每个可能的公式并找到所有可能的括号,而不需要重复

重复的示例:
(a+b)*c
a*(b+c)


注意:这是重复的,因为每个可能的方程都在测试中,在某个点上,
a+b
将变成
b+c
,因此
*c
将变成
*a

这一个将起作用,但是它确实有很多表达式,它们将指向同一事物,例如
x-x
x/x
,用许多不同的事物代替
x
。然而,由于结合性或交换性,它避免了琐碎的重复

而且,所有可能的表达式的列表很快变得异常长。例如,对于4个变量和5个术语的所有表达式,可以得到其中的7845320个。使用生成器可以防止内存不足,但不会让它花费很长时间运行

def all_expressions(size, variables):
    def _all_expressions(_size):
        if _size == 1:
            for variable in variables:
                yield (variable, '')
        else:
            for subsize in range(1, _size//2 + 1):
                for expr1, type1 in _all_expressions(subsize):
                    for expr2, type2 in _all_expressions(_size - subsize):
                        if subsize < _size - subsize or expr1 <= expr2:
                            if type1 == '+':
                                if type2 != '+':
                                    yield ("({} + {})".format(expr2, expr1), '+')
                            else:
                                yield ("({} + {})".format(expr1, expr2), '+')
                            if type1 == '*':
                                if type2 != '*':
                                    yield ("({} * {})".format(expr2, expr1), '*')
                            else:
                                yield ("({} * {})".format(expr1, expr2), '*')
                        if type1 != '*':
                            yield ("({} / {})".format(expr1, expr2), '/')
                        if type1 != '+':
                            yield ("({} - {})".format(expr1, expr2), '-')
                        if subsize < _size - subsize:
                            if type2 != '*':
                                yield ("({} / {})".format(expr2, expr1), '/')
                            if type2 != '+':
                                yield ("({} - {})".format(expr2, expr1), '-')
    for expr, t in _all_expressions(size):
        yield expr

for expr in all_expressions(3, ['a', 'b', 'c']):
    print(expr)
def所有_表达式(大小、变量):
定义所有表达式(大小):
如果_size==1:
对于变量中的变量:
收益率(变量“”)
其他:
对于范围(1,_size//2+1)内的子项:
对于expr1,在所有表达式(子版)中键入1:
对于expr2,在所有表达式中键入2(\u size-subsize):

如果subzize<\u size-subzize或expr1此任务需要构建它们吗?不仅仅是计数?是的,要找到所有可能的方程式并将它们保存到列表@Iluvatary,您的计数似乎不一致。n=3的第一个示例是(a+b)/a,即仅计算变量,但后面的示例同时计算变量和运算符,例如,对于n=5,您带来(a+b)*b。n的确切含义是什么?@pentadecagon n包含变量和运算符。您可能需要研究如何为每个等式构建语法树或AST。这将解决括号问题,因为该信息存储在树的结构中。例如,
(a+b)*c
将存储为类似
*(+(a,b),c)
(其中
x(y,z)
表示节点
x
具有子节点
y
z
)。回答得好!当在末尾调用时,您只需要为所有表达式添加大小。是否有方法删除重复项,例如重复两次的
((b*b)/b)
?所有重复项(如果有帮助的话),(仅显示第二次+重复):
((b*b)/b
(b/(b/b))
((b/b)/b)
(b-(b-b))
((b-b)-b
((b+b)/b
((b+b)-b
(b/(b+b)),
(b-(b+b))
((b*b)/b
((b*b)-b
(b/(b/(b*b)),
(b/(b/b))
(b-(b/b))
((b-b)+b)
((b-b)*b)
((b-b)/b)
((b-b)-b)
(b-(b-b))
@RulerOfTheWorld我刚刚去掉了很多重复项。它确实需要对关联性/交换性逻辑进行一些调整。B哦,
应该是什么?对我不起作用!