取一串数字并插入+和 - 运算符

时间:2012-03-22 14:00:50

标签: python string recursion

我被这个看似微不足道的问题困扰了......

我想使用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

3 个答案:

答案 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(非常糟糕)。