在Python中循环循环?

时间:2013-12-06 05:45:08

标签: python iteration

我正在尝试在coderbyte的简单部分解决这个问题,提示符是:

让函数ArrayAdditionI(arr)获取存储在arr中的数字数组,如果数组中的任何数字组合可以添加到数组中的最大数字,则返回字符串true,否则返回字符串false。例如:如果arr包含[4,6,23,10,1,3],则输出应返回true,因为4 + 6 + 10 + 3 = 23.数组不会为空,不包含所有相同的元素,并且可能包含负数。

这是我的解决方案。

def ArrayAddition(arr):
arr = sorted(arr, reverse=True)
large = arr.pop(0)
storage = 0
placeholder = 0
for r in range(len(arr)):
    for n in arr:
        if n + storage == large: return True
        elif n + storage < large: storage += n
        else: continue
    storage = 0
    if placeholder == 0: placeholder = arr.pop(0)
    else: arr.append(placeholder); placeholder = arr.pop(0)
return False

print ArrayAddition([2,95,96,97,98,99,100])

我甚至不确定这是否正确,但它似乎涵盖了我插入的所有数字。我想知道是否有更好的方法通过我不知道的算法来解决这个问题。我正在考虑for for for for for,et循环可以解决问题,但我不知道如何做到这一点。

我的想法是用A + B,A + C,A + D ...... A + B + C ...... A + B + C + D + E

完成

例如

for i in range(len(arr):
print "III: III{}III".format(i)
storage = []
for j in range(len(arr):
    print "JJ: II({}),JJ({})".format(i,j)

    for k in range(len(arr):
        print "K: I{}, J{}, K{}".format(i,j,k)

我已经搜遍了所有的并发现了itertool的建议,但我想知道是否有办法更加原始地编写这段代码。

感谢。

6 个答案:

答案 0 :(得分:4)

递归解决方案:

def GetSum(n, arr):
    if len(arr) == 0 and n != 0:
        return False
    return (n == 0 or  
      GetSum(n, arr[1:]) or  
      GetSum(n-arr[0], arr[1:]))

def ArrayAddition(arr):
    arrs = sorted(arr)
    return GetSum(arrs[-1], arrs[:-1])

print ArrayAddition([2,95,96,97,98,99,100])

当所需的总和不为零且数组中没有项目时,GetSum函数返回False。然后检查3个案例:

  1. 如果所需的总和n为零,则达到目标。
  2. 如果我们可以在删除第一个项目后获得剩余项目的总和,那么就可以实现目标。
  3. 如果我们可以在列表的其余部分获得所需的总和减去列表的第一个元素,那么目标就实现了。

答案 1 :(得分:2)

您的解决方案不起作用。

>>> ArrayAddition([10, 11, 20, 21, 30, 31, 60])
False

简单的解决方案是使用itertools迭代输入的所有子集(不包含最大数字):

def subsetsum(l):
    l = list(l)
    target = max(l)
    l.remove(l)
    for subset_size in xrange(1+len(l)):
        for subset in itertools.combinations(l, subset_size):
            if sum(subset) == target:
                return True
    return False

如果要避免使用itertools,则需要直接生成子集。这可以通过以二进制计数并使用设置位来确定要选择的元素来实现:

def subsetsum(l):
    l = list(l)
    target = max(l)
    l.remove(l)
    for subset_index in xrange(2**len(l)):
        subtotal = 0
        for i, num in enumerate(l):
            # If bit i is set in subset_index
            if subset_index & (1 << i):
                subtotal += num
        if subtotal == target:
            return True
    return False

答案 2 :(得分:0)

更新:我忘了您要检查所有可能的组合。请改用:

def ArrayAddition(l):
    for length in range(2, len(l)):
        for lst in itertools.combinations(l, length):
            if sum(lst) in l:
                print(lst, sum(lst))
                return True
    return False

单线解决方案:

>>> any(any(sum(lst) in l for lst in itertools.combinations(l, length)) for length in range(2, len(l)))

希望这有帮助!

答案 3 :(得分:0)

生成powerset的所有总和并根据max

测试它们
def ArrayAddition(L):
    return any(sum(k for j,k in enumerate(L) if 1<<j&i)==max(L) for i in range(1<<len(L)))

你可以通过做一些预处理来改善这一点 - 首先找到最大值并从L

中删除它

答案 4 :(得分:0)

另一种方法......

<强>代码:

import itertools
def func(l):
    m = max(l)
    rem = [itertools.combinations([x for x in l if not x == m],i) for i in range(2,len(l)-1)]
    print [item for i in rem for item in i if sum(item)==m ]


if __name__=='__main__':
    func([1,2,3,4,5])

<强>输出:

[(1, 4), (2, 3)]  

希望这会有所帮助.. :)

答案 5 :(得分:0)

如果我正确地理解了这个问题,那么只需返回你想要的东西:

2*max(a)<=sum(a)