【问题标题】:Python set sequence of numbers to add or subtract for certain resultPython设置数字序列以添加或减去某些结果
【发布时间】:2015-10-16 14:01:21
【问题描述】:

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

有没有办法在不重新发明轮子的情况下做到这一点,例如模块?

编辑:更多信息:

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

编辑:

让我们假设等式中没有任何步骤导致答案大于 1000。

【问题讨论】:

  • 这需要减少假设。给我们一些示例数据并解释你想要什么。
  • 解决了这个问题。
  • 我很想看到一个数学家把这个定理命名为..现在不记得了!
  • 如果您正在寻找一种比@Kevin 的时间复杂度更好的算法,但不是特定于python,cs.stackexchange.com 可能是更合适的场所。

标签: python algorithm math sequence iterable


【解决方案1】:

最简单的方法是暴力破解所有可能的正负组合,并返回第一个具有正确总和的组合。您可以使用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

这样做的缺点是它在 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"

结果:

[5, 4, -3, 2, -1]

【讨论】:

  • 我在想一些更复杂的东西,但这似乎可行!
  • 序列中可能的数字数量太多了,无法像这样处理它。让我们假设等式中的任何步骤都不会产生大于 1000 的答案。
  • 如果还有一个 lower 限制为 -1000,这会让事情变得更容易...已编辑。
  • 我想补充一点,如果有人使用 Python 3,请使用 d.items() 而不是 d.iteritems()。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-20
相关资源
最近更新 更多