找到4个数字,其总和为给定数字

时间:2017-08-31 17:41:42

标签: python python-3.x

需要从列表中找到4个数字,其总和将等于给定的“sum _”

def find_four(nums, sum_):
    if len(nums) < 4:
        return
    i = 0
    i2 = 1
    i3 = 2
    i4 = 3
    while True:
        num_sum = nums[i] + nums[i2] + nums[i3] + nums[i4]
        if num_sum == sum_:
            return [nums[i], nums[i2], nums[i3], nums[i4]]
        elif i == len(nums) - 4:
            return
        elif i2 == len(nums) - 3:
            i += 1
        elif i3 == len(nums) - 2:
            i2 += 1
        elif i4 == len(nums) - 1:
            i3 += 1
        elif i4 != len(nums):
            i4 += 1

我的代码适用于某些列表,例如: find_four([1, 1, 1, 5, 1, 5, 7], 10)find_four([4, 6, 1, 4, 1, 6, 2], 13)。 但它不适用于一些例如' find_four([7, 5, 1, 4, 1, 6, 2], 11)(需要打印7, 1, 1, 2) 怎么了 ?? :(

5 个答案:

答案 0 :(得分:5)

没有嵌套循环的原因。

import itertools
import operator as op
from functools import reduce

def find_N(nums, target, N=4):
    for combo in list(itertools.combinations(nums, N)):
        if reduce(op.add, combo) == target:
            return combo
    return []

>>> find_N([1,2,3,4,5,6,7,8], target=10)
(1, 2, 3, 4)

>>> find_N([1,2,3,4,5,6,7,8], target=10, N=3)
(1, 2, 7)

>>> find_N([1,2,3,4,5,6,7,8], target=10, N=2)
(2, 8)

观察:

  • 很多东西都是用Python预先构建的,使用它们而不是重新创建方向盘
  • 概括是好的。如果N从4
  • 更改,您不想更改您的功能
  • sum不是一个声音变量名称,因为它破坏了该名称的内置函数

答案 1 :(得分:2)

你可能应该在处理它之前对nums进行排序,然后就像你正在做的那样。

def find_four(nums, sum_):
    if len(nums) < 4:
        return
    nums = sorted(nums)  # Sort nums here
    i = 0
    i2 = 1
    i3 = 2
    i4 = 3
    while True:
        num_sum = nums[i] + nums[i2] + nums[i3] + nums[i4]
        if num_sum == sum_:
            return [nums[i], nums[i2], nums[i3], nums[i4]]
        elif i == len(nums) - 4:
            return
        elif i2 == len(nums) - 3:
            i += 1
        elif i3 == len(nums) - 2:
            i2 += 1
        elif i4 == len(nums) - 1:
            i3 += 1
        elif i4 != len(nums):
            i4 += 1

这将为7, 1, 1, 2生成find_four([7, 5, 1, 4, 1, 6, 2], 11)。请注意,不会保留数字的顺序。

答案 2 :(得分:1)

只需使用itertools.combinations即可。下面的代码将返回总和等于sum_的所有对。我通过在参数中传递4个默认值来设置combinations以获取4个数字。您可以通过更改目标来交替用于计算总和的数量。

import itertools
from itertools import combinations
def find_four(nums, sum_,target=4):
    return([pair for pair in itertools.combinations(nums,target) if sum(pair) == sum_])

nums=[1,2,3,4,1,5,6,7,8,9,10,11,12]

示例: -

>>> find_four([1,2,3,4,1,5,6,7,8,9,10,11,12],10)
[(1, 2, 3, 4), (1, 2, 1, 6), (1, 3, 1, 5), (2, 3, 4, 1)]
>>>find_four([1,2,3,4,1,5,6,7,8,9,10,11,12],10,3)
[(1, 2, 7), (1, 3, 6), (1, 4, 5), (1, 1, 8), (2, 3, 5), (2, 1, 7), (3, 1, 6), (4, 1, 5)]

答案 3 :(得分:0)

使用4个循环

可以更简单
def find_four(arr, sum_):
    for i in range(len(arr)):
        for j in range(i + 1, len(arr)):
            for t in range(j + 1, len(arr)):
                for k in range(t + 1, len(arr)):
                    if arr[i] + arr[j] + arr[t] + arr[k] == sum_:
                        return [arr[i],arr[j],arr[t],arr[k]]
    return []

<强>输入

find_four([1, 1, 1, 5, 1, 5, 7], 10)
find_four([4, 6, 1, 4, 1, 6, 2], 13)
find_four([7, 5, 1, 4, 1, 6, 2], 11)

<强>输出

[1, 1, 1, 7]
[4, 6, 1, 2]
[7, 1, 1, 2]

答案 4 :(得分:0)

我注意到问题中的每个数字集合都是 multiset ,而不是一组。也就是说,每个集合至少包含一个成员的重复。这保证是这种情况,计算所有多集合组合可以更合适,从而避免处理重复组合。

>>> from sympy.utilities.iterables import multiset_combinations
>>> def find_four(nums, sum_):
...     for c in multiset_combinations(nums, 4):
...         if sum(c) == sum_:
...             return c
...     return {}
... 
>>> find_four([1, 1, 1, 5, 1, 5, 7], 10)
[1, 1, 1, 7]
>>> find_four([4, 6, 1, 4, 1, 6, 2], 13)
[1, 2, 4, 6]
>>> find_four([7, 5, 1, 4, 1, 6, 2], 11)
[1, 1, 2, 7]