取一串数字并插入 + 和 - 运算符
Posted
技术标签:
【中文标题】取一串数字并插入 + 和 - 运算符【英文标题】: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
【问题讨论】:
【参考方案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)。
【讨论】:
以上是关于取一串数字并插入 + 和 - 运算符的主要内容,如果未能解决你的问题,请参考以下文章
编写一个程序,该程序接受两个数字和一个像 (+,-,*, /) 这样的运算符作为命令行参数,并执行运算符指示的操作 [重复]