我被这个看似微不足道的问题困扰了......
我想使用python来获取一串数字(例如"123"
)并创建一个列表,其中包含"+"
或"-"
的所有可能表达式(或者没有任何表达式)所有)都可以插入任何数字之间。
对于示例"123"
,列表将是:
["123","12+3","12-3","1+23","1+2+3","1+2-3","1-23","1-2+3","1-2-3"]
如果数字串的长度为N,则列表应包含3 ^(N-1)个字符串。
我觉得这应该以递归的方式完成,但我不知道如何找出如何返回3个不同的选项(+, - ,None)。
我认为该函数的基本情况应为:
def options(string):
if len(string) == 1:
return string
else:
#This is where I am stuck
答案 0 :(得分:9)
使用itertools.product()
:
def plus_minus(s):
for t in itertools.product(["", "+", "-"], repeat=len(s) - 1):
yield "".join(itertools.chain.from_iterable(zip(s, t))) + s[-1]
示例:
>>> list(plus_minus("123"))
['123', '12+3', '12-3', '1+23', '1+2+3', '1+2-3', '1-23', '1-2+3', '1-2-3']
这是一个递归解决方案:
def plus_minus(s):
if len(s) <= 1:
yield s
return
for x in ["", "+", "-"]:
for y in plus_minus(s[1:]):
yield s[0] + x + y
我认为这里的递归解决方案确实更清晰。
答案 1 :(得分:6)
它有点密集,但itertools
是你的朋友:
import itertools as itr
ops = ["+","-",""]
expr = "123"
vals = itr.product(ops,repeat=len(expr)-1)
print [''.join([x+y for x,y in zip(expr,v)])+expr[-1] for v in vals]
['1 + 2 + 3','1 + 2-3','1 + 23','1-2 + 3','1-2-3','1-23','12 + 3','12 -3','123']
这里真正的魔力来自函数product
,它使用替换的正确数量的组合(也可以使用)。我们怎么知道我们需要多少个术语?看起来您只能在表达式的任意两个值之间插入一个操作,因此我们需要插入len(expr)-1
个值。查看输出:
list(itr.product([1,3,5],repeat=2))
[(1,1),(1,3),(1,5),(3,1),(3,3),(3,5),(5,1),(5,3) ),(5,5)]
即。我们通过从列表中获取顺序很重要的两个元素来获得每个组合。答案中的最后一个打印行只是将两个表达式放在一起的粘合剂,确保最后一个术语expr[-1]
被添加到最后。
答案 2 :(得分:0)
将其分解为递归子问题:对于一串字符索引0..N(包括)取0和1,递归生成字符2..N的解决方案数组(让这个数组为A),产生另一个数组其中0和1的每个组合(例如01,0 + 1等)都预先添加到A中的每个解中。如果没有剩下的字符,只需返回组合。
但请注意,如果盲目实施,上述说明可能在空间和效率方面都会出现O(非常糟糕)。