问题描述
我有一串数字,string="123456789"
,我想打印所有变体,在数字之间插入加法、减法或什么都不做,得到 100。大多数数字的顺序保持不变。
示例:1+2+3-4+5+6+78+9=100
我什至不知道如何开始。我想列出所有可能的 +-x 组合(x 代表无)并插入每个组合并进行测试,但这似乎需要很长时间。 有什么建议吗?
解决方法
您可以使用 itertools
模块中的 product
和 zip_longest
来实现。我们建立所有可能的组合,然后evaluate 只过滤那些评估为 100 的组合。
from itertools import product,zip_longest
operations = ['-','+','']
s = '123456789'
combinations = (zip_longest(s,ops,fillvalue='') for ops in product(operations,repeat=8))
to_eval = (''.join(i + j for i,j in combination) for combination in combinations)
print([i for i in to_eval if eval(i) == 100])
>>> ['1+2+3-4+5+6+78+9','1+2+34-5+67-8+9','1+23-4+5+6+78-9','1+23-4+56+7+8+9','12-3-4+5-6+7+89','12+3-4+5+67+8+9','12+3+4+5-6-7+89','123-4-5-6-7+8-9','123-45-67+89','123+4-5+67-89','123+45-67+8-9']
eval()
本质上并不坏,只是如果任何用户输入可以进入您正在评估的东西(这里不是这种情况),它就会导致重大的安全问题。为个人项目执行此操作很好。在生产环境中,您可能希望自己解析字符串或寻找不同的方法。
优化说明请看这里:Most pythonic way to interleave two strings
,a = ['+','-','']
nb = '123456789'
target = 100
N = len(nb)-1
for n in range(3**N):
attempt = nb[0]
for i in range(N):
attempt += a[n % 3]
attempt += nb[i+1]
n = n // 3
if eval(attempt) == target:
print(attempt,' = ',target)
导致
1+23-4+56+7+8+9 = 100
12+3-4+5+67+8+9 = 100
1+2+34-5+67-8+9 = 100
1+2+3-4+5+6+78+9 = 100
123-4-5-6-7+8-9 = 100
123+45-67+8-9 = 100
1+23-4+5+6+78-9 = 100
12-3-4+5-6+7+89 = 100
12+3+4+5-6-7+89 = 100
123-45-67+89 = 100
123+4-5+67-89 = 100