【问题标题】:Taking a string of numbers and inserting + and - operators取一串数字并插入 + 和 - 运算符
【发布时间】:2012-04-07 02:29:33
【问题描述】:

我被这个看似微不足道的问题难住了......

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

【问题讨论】:

    标签: python string recursion


    【解决方案1】:

    这是一个使用 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
    

    我认为这里的递归解决方案确实更干净。

    【讨论】:

      【解决方案2】:

      有点密集,不过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] 被添加到末尾。

      【讨论】:

        【解决方案3】:

        将其分解为递归子问题:对于一串字符索引 0..N(包括)取 0 和 1,递归生成字符 2..N 的解数组(设此数组为 A),产生另一个数组其中 0 和 1 的每个组合(例如 01、0+1 等)都添加到 A 中的每个解中。如果没有更多字符,则返回组合。

        但请注意,如果盲目实施,上述描述可能在空间和效率上都运行 O(abysmal)。

        【讨论】:

          猜你喜欢
          • 2012-05-10
          • 2023-04-05
          • 1970-01-01
          • 1970-01-01
          • 2020-10-06
          • 1970-01-01
          • 1970-01-01
          • 2012-09-19
          • 2016-05-18
          相关资源
          最近更新 更多