Это сработает, но у него есть много выражений, которые приходят к одному и тому же, например, 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)