Python 2.7 - 在列表中查找添加到另一个数字的数字组合

时间:2015-06-08 23:46:19

标签: python python-2.7 math

我想要做的是找到一种方法,我可以让我的代码返回添加到变量的列表中的所有值组合,将每个答案作为列表返回。例如,

    target_number = 8
    usingnumbers =  [1, 2, 4, 8]
    returns:
    [8]
    [4, 4]
    [4, 2, 2]
    [4, 2, 1, 1]
    [4, 1, 1, 1, 1]
    [2, 2, 1, 1, 1, 1]
    [2, 1, 1, 1, 1, 1, 1]
    [1, 1, 1, 1, 1, 1, 1, 1]

等等。我希望丢弃重复的值,例如[4,2,2],[2,4,2],[2,2,4]在技术上都是有效的,但我只是喜欢其中一个要显示。理想情况下,我希望代码也返回每个数字出现在每个列表中的次数,但我确信我可以为自己这样做。

3 个答案:

答案 0 :(得分:0)

不会为你编写代码,但有一个主要的想法:

函数F(n, (k1, k2, .. km)) - 返回一组数字列表:

{(a11, ... a1i), (a21, ... a2i), ... (aj1, ... aji )}

有经常性的关系:

F(n, (k1, k2, .., km)) = union(
  (k1) (+) F(n - k1, (k1, k2, ... km)),
  (k2) (+) F(n - k2, (k2, k3, ... km)),
  ...
  (km) (+) F(n - km, (km))
)

操作a (+) ba'的每个项目附加b

有很多极端情况,但它取决于你。

答案 1 :(得分:0)

在伪代码中:

  1. 从您的组合号码中减去您列表中的最大号码,跟踪您开始的号码
  2. 循环,直到你不能再
  3. 继续前进至第二大等
  4. 再次开始此循环,但从小于上一循环开始的数字开始。
  5. 没那么困难。

答案 2 :(得分:0)

这是问题的完整解决方案,整个功能是一个伪装的大发电机,第一个for循环使用最小的硬币,而在第二个中,最小的硬币被丢弃而下一个大硬币被丢弃将成为我们递归函数的基础。如果当前硬币的总和等于给定的数字,则返回包含硬币的列表,如果总和大于那个列表被丢弃的数字。

def changes(number, coins_available, coins_current):
    if sum(coins_current) == number:
        yield coins_current
    elif sum(coins_current) > number:
        pass
    elif coins_available == []:
        pass
    else:
        for c in changes(number, coins_available[:], coins_current + [coins_available[0]]):
            yield c
        for c in changes(number, coins_available[1:], coins_current):
            yield c

n = 40
coins = [1,2,5,10,20,50,100]

solutions = [sol for sol in changes(n, coins, [])]

for sol in solutions:
    print sol

print 'least coins used solution:', min(solutions, key=len)
print 'number of solutions', len(solutions)