Python为特定结果设置要加或减的数字序列

Python为特定结果设置要加或减的数字序列,python,algorithm,math,sequence,iterable,Python,Algorithm,Math,Sequence,Iterable,在这个假设场景中,我有一个已知但随机长度的序列,我需要将序列中的每个数字设置为加或减,以达到给定的输出并显示过程 有没有一种方法可以做到这一点而不必重新发明轮子,比如模块 编辑:更多信息: 我有一个数字序列,如:54321,我需要将每个数字设置为加(+)或减(-),以得到一个结果,如7。这种情况下的结果是5+4-3+2-1。只要有可能的结果,它可以是任何数字的序列。如果有多个正确答案,其中一个就可以了 编辑: 假设方程中的任何一步都不会得到大于1000的答案 最简单的方法是强制执行所有可能的加减

在这个假设场景中,我有一个已知但随机长度的序列,我需要将序列中的每个数字设置为,以达到给定的输出并显示过程

有没有一种方法可以做到这一点而不必重新发明轮子,比如模块

编辑:更多信息:

我有一个数字序列,如:54321,我需要将每个数字设置为加(+)或减(-),以得到一个结果,如7。这种情况下的结果是5+4-3+2-1。只要有可能的结果,它可以是任何数字的序列。如果有多个正确答案,其中一个就可以了

编辑:

假设方程中的任何一步都不会得到大于1000的答案


最简单的方法是强制执行所有可能的加减组合,并返回第一个具有正确总和的组合。您可以使用
itertools.product
来执行此操作

import itertools

def find_correct_operators(seq, total):
    signs = [-1,1]
    for item_signs in itertools.product(*[signs]*len(seq)):
        seq_with_signs_applied = [item*sign for item, sign in zip(seq, item_signs)]
        sum(seq_with_signs_applied)
        if sum(seq_with_signs_applied) == total:
            return item_signs

a = [5,4,3,2,1]
b = 7
signs = find_correct_operators(a,b)
if signs is not None:
    print "{} = {}".format(" ".join("{}{}".format("-" if sign == -1 else "+", item) for sign, item in zip(signs, a)), b)
else:
    print "No solution found"
结果:

+5 -4 +3 +2 +1 = 7
[5, 4, -3, 2, -1]
它的缺点是运行时间为O(2^N),因此它非常不适合任何长度大于(比如)20项的数字序列。到那时,您正在迭代超过一百万种可能的组合


编辑:如果你有一些极限L,并且方程中没有中间步骤的计算结果可能大于L或小于-L,那么你可以在O(N*L)时间内找到答案,这对于较小的L值来说是一个相当大的改进

seq = [5,4,-3,2,1]
goal = 7
limit = 1000
d = {0: []}
for item in seq:
    next_d ={}
    for intermediary_total, path in d.iteritems():
        for candidate in [-item, item]:
            next_total = intermediary_total + candidate
            if abs(next_total) <= limit:
                next_d[next_total] = path + [candidate]
    d = next_d

if goal in d:
    print d[goal]
else:
    print "no solution found"

这需要减少假设性。给我们一些示例数据并解释你想要的。解决了这个问题。我很想看到一位数学家为这个定理命名。。现在不记得了!如果你正在寻找一种时间复杂度比下面的@Kevin算法更好的算法,而该算法不是python特有的,那么这可能是更合适的选择。我正在考虑一种更复杂的算法,但它似乎有效!序列中可能包含的数字太多,无法像这样处理。让我们假设方程中的任何一步都不会得到大于1000的答案。如果还有一个下限-1000,这会使事情变得更容易。。。我想补充一点,如果有人正在使用Python 3,请使用d.items()而不是d.iteritems()。