Python - 所有组合,包括括号

Posted

技术标签:

【中文标题】Python - 所有组合,包括括号【英文标题】:Python - All combinations including brackets 【发布时间】:2019-02-12 18:51:08 【问题描述】:

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

一个例子是 (for 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 and 2 variables,我的代码找不到(a+b)*b的可能性

使用n=7 and 4 variables,找不到`(a+b)*(c+d)

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

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

注意:这是重复的,因为由于正在测试每个可能的等式,在某些时候a+b 将变为b+c,因此*c 将变为*a

【问题讨论】:

这个任务需要构建它们吗?不仅算数? 是的,找到所有可能的方程式并将它们保存到@Iluvatar 列表中 您的计数似乎不一致。您的 n=3 的第一个示例是 (a+b)/a,即只计算变量,但您后面的示例同时计算变量和运算符,例如对于 n=5,你带来 (a+b)*b。 n到底是什么意思? @pentadecagon n 包括变量和运算符 您可能想研究为每个方程构建语法树或 AST。这将解决括号问题,因为该信息存储在树的结构中。例如,(a+b)*c 将存储为类似*(+(a, b), c) 的内容(其中x(y, z) 表示节点x 具有子节点yz)。 【参考方案1】:

这个会起作用,但它确实有很多表达式会出现相同的东西,例如x-xx/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)

【讨论】:

很好的答案!您只需要在最后调用 all_expressions 时为其添加大小 有没有办法删除重复的((b * b) / b) 重复两次? 所有重复项(如果有帮助),(仅显示第 2 次以上重复):((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))9876 987654345@, ((b - b) / b), ((b - b) - b), (b - (b - b)) @RulerOfTheWorld 我刚刚删除了很多重复项。它确实需要对关联性/交换性逻辑进行一些调整。 btilly,&lt;&gt; 应该是什么?不适合我!

以上是关于Python - 所有组合,包括括号的主要内容,如果未能解决你的问题,请参考以下文章

9.9递归和动态规划——打印n对括号的所有有效组合(即左右括号正确配对)

经典问题——输出n对括号的所有组合

python 题目:斐波那契数列计算;题目:站队顺序输出;题目:合法括号组合的生成;题目:用户登录(三次机会)

Python删除方括号和它们之间的无关信息

2021-09-19:数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且有效的括号组合。

swift算法:数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。