此函数接受一串数字和一个目标整数,并打印所有可能的方式来插入运算符以达到所需的目标。在所有情况下,输出都必须按顺序包含所有数字;一个都不能省略。
#!/usr/bin/env python3
def find_expressions(digits, target):
if not (isinstance(digits, str) or isinstance(digits, list)) or not isinstance(target, int):
raise TypeError
if len(digits) != 5:
raise TypeError('digits must be of length 5')
solutions = []
operators = ('', ' + ', ' - ', ' * ', ' / ')
for i in operators:
for j in operators:
for k in operators:
for l in operators:
s = digits[0] + i + digits[1] + j + digits[2] + k + digits[3] + l + digits[4]
try:
if eval(s) == target:
solutions.append(s + ' == {}'.format(target))
except (ZeroDivisionError, SyntaxError):
pass
print('\n'.join(solutions))
它不是很漂亮,但它确实有效。问题是它只接受长度为 5 的字符串。如何让它接受任意长度的字符串? (例如,调用 find_expressions('12345678', 2) 应该是有效的。)我想我需要用递归替换 for 循环,但我在不知道如何实现这一点。
示例输出
调用 find_expressions('75228', 5) 打印:
7 + 5 + 2 / 2 - 8 == 5
7 * 5 - 22 - 8 == 5
7 * 5 - 2 - 28 == 5
警告
我对循环遍历所有可能性的整个蛮力方法不满意。如果总体上有更好的算法,我想听听。 但是,这个问题是关于让这个函数接受任意长度的输入,同时进行尽可能小的更改。
请您参考如下方法:
import itertools
def find_expressions(digits, target):
if not (isinstance(digits, str) or isinstance(digits, list)) or not isinstance(target, int):
raise TypeError
solutions = []
operators = ('', ' + ', ' - ', ' * ', ' / ')
for ops in itertools.product(operators, repeat=len(digits)-1):
s = digits[0] + ''.join(op + digit for op, digit in zip(ops, digits[1:]))
try:
if eval(s) == target:
solutions.append(s + ' == {}'.format(target))
except (ZeroDivisionError, SyntaxError):
pass
print('\n'.join(solutions))
